2017-05-03 24 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의 출력의 일부입니다 : 여기에 생성자입니다 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) 

다른 오류는 String::String(String const&) 다시 operator new[]에 추적. 그러나 무엇이 잘못 되었습니까? 그리고이 오류를 피하기 위해 생성자를 어떻게 다시 작성합니까?

+0

[MCVE]를 게시하십시오. –

+0

생성자가'mStr'에 값을 할당 한 다음 그것을 무시하고'mCopy'를 호출하여'mStr'에 새로운 값을 할당하는 이유는 무엇입니까? 그게 무슨 의미가 있니? 또한, 왜'mCopy'는 이미 종료 된 문자열을 종료합니까? –

답변

3

이 오류는이 라인에 의해 생성된다 :

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

n+1가 할당 된 크기 지난 1입니다.

mStr[n] = '\0'; 

이 줄을 제거하는 것이 올바른 것입니다 : null 종결이가는 곳 문자열의 몸, 0n-1를 통해 인덱스에 포함 된 위치 때문에, 대신 n를 사용해야하기 때문에 인덱스 n입니다 strcpy은 결과를 null로 종료하기 때문입니다. memcpy과 같이 널 종료자를 수동으로 배치하는 것은 사용자를 위해 수행하지 않는 기능을 사용할 때 필요합니다.