2017-05-03 69 views
-1

我有一個帶有字符串鍵和我自己的String類的AVL樹。爲了解決另一個問題,我不得不向String添加一個拷貝構造函數。但是,valgrind會報告它的錯誤。這裏的構造函數:C + + - Valgrind:無效的寫入大小爲1

String::String(const String& s){ 
    try { 
     mStr = new char[1]; 
    } 
    catch (const bad_alloc& e){ 
     printf("ERROR: No memory\n"); 
     exit(0); 
    } 
    mStr[0]='\0'; 
    mCopy(s); 
} 

void String::mCopy(const String& s){ 
    // delete[] mStr; 
    size_t n = s.Length(); 
    try{ 
     mStr = new char[n + 1]; 
    } 
    catch (const bad_alloc& e){ 
     printf("ERROR: No memory\n"); 
     exit(0); 
    } 
    strcpy(mStr, s.mStr); 
    mStr[n + 1] = '\0'; 
} 

這裏添加一個字符串鍵,我的AVL樹後是Valgrind的輸出的一部分:

==7005== Invalid write of size 1 
==7005== at 0x4013A1: String::mCopy(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x401213: String::String(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x40182D: main (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== Address 0x5ad450d is 0 bytes after a block of size 61 alloc'd 
==7005== at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==7005== by 0x40136B: String::mCopy(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x401213: String::String(String const&) (in /home/ezrafell/Desktop/DA2final/DA3.o) 
==7005== by 0x40182D: main (in /home/ezrafell/Desktop/DA2final/DA3.o) 

由Valgrind的報告的其他錯誤也追溯到operator new[]String::String(String const&)。但是它有什麼問題?我該如何重寫構造函數以避免此錯誤?

+0

請發佈[MCVE]。 –

+0

爲什麼你的構造函數爲'mStr'賦值,然後忽略它,並通過調用'mCopy'來爲'mStr'賦值?這有什麼意義?另外,爲什麼'mCopy'終止已經終止的字符串? –

回答

3

該錯誤是由該生產線生產:

mStr[n + 1] = '\0'; 

n+1是一個過去的分配的大小。您需要使用n代替,因爲字符串的身體位於索引0通過n-1,包容性,因此指數n就是空終止雲:

mStr[n] = '\0'; 

注意刪除這條線將是正確的,因爲strcpy null-termination其結果。當您使用不適合您的功能時,需要手動放置空終止符,例如memcpy