我是valgrind的新手,所以我可能做错了什么,但是如果valgrind报告的更多自由而不是分配,我该怎么办?
在这里有一个SSCCE:
#include <cstring>
class something
{
protected:
char* ptr;
public:
something() {ptr = NULL;}
something(const char* value) {
ptr = new char[strlen(value)+1]; strcpy(ptr, value);
}
~something() {delete[] ptr; ptr = NULL;}
};
int main()
{
something x;
x = "123";
return 0;
}
编译很好,也运行得很好,但valgrind说
==15925== Invalid free() / delete / delete[]
==15925== at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364)
==15925== by 0x8048689: something::~something() (test.cpp:12)
==15925== by 0x80485F5: main (test.cpp:19)
==15925== Address 0x42b7028 is 0 bytes inside a block of size 4 free'd
==15925== at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364)
==15925== by 0x8048689: something::~something() (test.cpp:12)
==15925== by 0x80485E5: main (test.cpp:18)
==15925==
==15925== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 1)
==15925== malloc/free: in use at exit: 0 bytes in 0 blocks.
==15925== malloc/free: 1 allocs, 2 frees, 4 bytes allocated.
==15925== For counts of detected errors, rerun with: -v
==15925== All heap blocks were freed -- no leaks are possible.
我不确定为什么。
当然,我可以做出有根据的猜测 - 显然,违规行是它所说的x = "123";
,如果你评论出来,一切都很好。但是为什么编译器认为这是正确的,即使使用-Wall -Wextra -pedantic
?我忘记了编译器开关,它可以告诉我这个程序有问题吗?
答案 0 :(得分:1)
x = "123"
等同于x = something("123")
,它调用隐式复制赋值运算符。临时something
被破坏,但是x
也是如此,delete []
都是{{1}}相同的原始指针。
解决方案是遵循Rule of Three,或使用智能指针/容器为您进行内存管理。
答案 1 :(得分:1)
您忘记实施 Rule of three 您应该提供复制构造函数以及复制赋值运算符。
x = "123";
调用隐式生成的复制赋值运算符,该运算符生成对象的浅表副本,一旦临时被销毁,析构函数就会释放已分配的内存,使指针成员保持为悬空指针。
答案 2 :(得分:0)
您的something
类包含一个原始指针,该指针未由其(编译器提供的)复制构造函数和赋值运算符正确管理。不要使用原始指针,或者如果必须,请更仔细地定义类方法。但实际上,不要使用原始指针。