2017-05-03 5 views
-1

私は文字列キーを持つAVLツリーと独自のStringクラスを持っています。別の問題を修正するために、コピーコンストラクタを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ので報告

他のエラーもString::String(String const&)operator new[]に遡ります。しかし、それは何が問題なのですか?そして、このエラーを回避するために、コンストラクタをどのように書き直すのですか?

+0

[MCVE]を投稿してください。 –

+0

なぜコンストラクタは 'mStr'に値を代入し、それを無視して' mStr'に 'mCopy'を呼び出すことで新しい値を割り当てますか?それは何の意味ですか?また、なぜ 'mCopy'はすでに終了している文字列を終了するのですか? –

答えて

3

エラーは、このラインにより製造される:

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

n+1が割り当てサイズ過去のものです。文字列の本体がn-1を通じてインデックス0に位置しているため、ヌルターミネータがどこに行くのインデックスnがあるので、あなたは、包括的、代わりにnを使用する必要があります。

mStr[n] = '\0'; 

この行を削除する注意は、正しいだろうstrcpyはその結果をヌル終了します。 memcpyのような、あなたのために機能しない関数を使用する場合は、ヌルターミネータを手動で配置する必要があります。

関連する問題