3

我是 valgrind 的新手,所以我可能做错了什么,但是如果 valgrind 报告的 frees 比 allocs 多,我该怎么办?

在这里获得了 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? 我是否忘记了可以告诉我该程序有问题的编译器开关?

4

3 回答 3

1

x = "123"等效于x = something("123"),它调用隐式复制赋值运算符。临时something被破坏了,但随后也是如此x,两者都是delete []相同的原始指针。

解决方案是遵循三规则,或者使用智能指针/容器为您进行内存管理。

于 2012-04-28T12:50:32.503 回答
1

你忘了执行三法则
您应该提供一个复制构造函数以及复制赋值运算符。

x = "123";

调用隐式生成的复制赋值运算符,该运算符生成对象的浅拷贝,一旦临时对象被销毁,析构函数就会释放分配的内存,将指针成员作为悬空指针。

于 2012-04-28T12:50:45.313 回答
0

您的something类包含一个未由其(编译器提供的)复制构造函数和赋值运算符正确管理的原始指针。不要使用原始指针,或者如果必须,更仔细地定义你的类方法。但实际上,不要使用原始指针。

于 2012-04-28T12:50:37.293 回答