2014-04-21 139 views
0

我的test.cpp包含以下代碼。我用valgrind和valgrind對它進行了描述,顯示錯誤。我錯過了什麼?將char *轉換爲std :: string的大小1無效讀取

#include<string> 
#include<cstring> 
#include<iostream> 

void TestString(std::string & str) 
{ 
    char * tmpBuff = new char[3]; 
    tmpBuff[0] = 'f'; 
    tmpBuff[1] = 'o'; 
    tmpBuff[2] = 'o'; 
    str = tmpBuff; 
    delete [] tmpBuff; 
} 

int main(int argc, char* argv[]) 
{ 
    std::string test_string; 
    TestString(test_string); 
    std::cout<<test_string; 
    return 0; 
} 

的valgrind日誌

==5026== Invalid read of size 1 
==5026== at 0x4A07F64: strlen (mc_replace_strmem.c:403) 
==5026== by 0x347E29E14B: std::string::operator=(char const*) (in /usr/lib64/libstdc++.so.6.0.13) 
==5026== by 0x4009AD: TestString(std::string&) (test.cpp:11) 
==5026== by 0x4009EC: main (test.cpp:18) 
==5026== Address 0x4c22043 is 0 bytes after a block of size 3 alloc'd 
==5026== at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363) 
==5026== by 0x400979: TestString(std::string&) (test.cpp:7) 
==5026== by 0x4009EC: main (test.cpp:18) 
+0

任何人都可以請解釋,即使'str = tmpBuff; delete [] tmpBuff;','std :: cout << test_string;'是否有效? –

+2

@MatHatter:'str = tmpBuff'不是指針副本; 'std :: string'重載'='來複制指向的字符。 – user2357112

+0

@MadHatter'tmpBuff'是一個'char *',所使用的字符串構造函數是建立其內部數據緩衝區(並失敗,因爲它不是null結束),然後'delete []'取消分配內存。禁止終止錯誤,這很好,如果奇怪。 – juanchopanza

回答

2

請嘗試以下修復

void TestString(std::string & str) 
{ 
    char * tmpBuff = new char[4]; // <<< 
    tmpBuff[0] = 'f'; 
    tmpBuff[1] = 'o'; 
    tmpBuff[2] = 'o'; 
    tmpBuff[3] = '\0'; // <<< 
    str = tmpBuff; 
    delete [] tmpBuff; 
} 

C風格的字符串需要終止\0字符。

3

tmpBuff缺少終止\0

它應該包含4個字符:'f', 'o', 'o', '\0'

1

您撥打的std::string(const char*)構造函數期望nul terminated string。你沒有通過它,所以結果是未定義的行爲。構造函數會嘗試閱讀,直到找到\0

所以,傳遞一個nul終止的字符串,一切都會好的。

相關問題