C++ - Valgrind:大小为 1 的无效写入
C++ - Valgrind: Invalid write of size 1
我有一个带有字符串键的 AVL 树,还有我自己的字符串 class。为了解决另一个问题,我不得不向 String 添加一个复制构造函数。但是,valgrind 报告错误。这是构造函数:
String::String(const String& s){
try {
mStr = new char[1];
}
catch (const bad_alloc& e){
printf("ERROR: No memory\n");
exit(0);
}
mStr[0]='[=10=]';
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] = '[=10=]';
}
这是将字符串键添加到我的 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[]
。但它有什么问题呢?以及如何重写构造函数以避免此错误?
此行产生错误:
mStr[n + 1] = '[=10=]';
n+1
超过了分配的大小。您需要改用 n
,因为字符串的主体位于索引 0
到 n-1
之间,包括在内,因此索引 n
是空终止符所在的位置:
mStr[n] = '[=11=]';
注意 删除此行也是正确的,因为 strcpy
以 null 终止其结果。当您使用不为您做的函数时,例如 memcpy
.
,则需要手动放置空终止符
我有一个带有字符串键的 AVL 树,还有我自己的字符串 class。为了解决另一个问题,我不得不向 String 添加一个复制构造函数。但是,valgrind 报告错误。这是构造函数:
String::String(const String& s){
try {
mStr = new char[1];
}
catch (const bad_alloc& e){
printf("ERROR: No memory\n");
exit(0);
}
mStr[0]='[=10=]';
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] = '[=10=]';
}
这是将字符串键添加到我的 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[]
。但它有什么问题呢?以及如何重写构造函数以避免此错误?
此行产生错误:
mStr[n + 1] = '[=10=]';
n+1
超过了分配的大小。您需要改用 n
,因为字符串的主体位于索引 0
到 n-1
之间,包括在内,因此索引 n
是空终止符所在的位置:
mStr[n] = '[=11=]';
注意 删除此行也是正确的,因为 strcpy
以 null 终止其结果。当您使用不为您做的函数时,例如 memcpy
.