2017-05-03 145 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