2013-04-28 61 views
0

我用指针来创建一个数组,然后在析构函数Valgrind的抱怨内存泄漏,但我打电话new和delete

class cBuffer{ 
    private: 
    struct entry { 
     uint64_t key; 
     uint64_t pc; 
    }; 
    entry *en; 
    public: 
    cBuffer(int a, int b, int mode) 
    { 
     limit = a; 
     dist = b; 
     md = mode; 
     en = new entry[ limit ]; 
     for (int i=0; i<limit; i++) { 
     en[i].key = 0; 
     en[i].pc = 0; 
     } 
    }; 
    ~cBuffer() { delete [] en; } 
    ... 
    } 

在另一大类我用cBuffer这样写道删除过程:

class foo() { 
    cBuffer *buf; 
    foo() 
    { 
    buf = new cBuffer(gSize, oDist, Mode); 
    } 
}; 

然而,Valgrind的抱怨新的运营商

==20381== 16,906,240 bytes in 32 blocks are possibly lost in loss record 11,217 of 11,221 
==20381== at 0x4A0674C: operator new[](unsigned long) (vg_replace_malloc.c:305) 
==20381== by 0x166D92F8: cBuffer::cBuffer(int, int, int) 
+4

您没有遵循三个规则。 – 2013-04-28 14:37:26

+0

见:https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming) – 2013-04-28 14:40:43

+0

@mahmood:见[这里](http://stackoverflow.com/questions/4172722);如果你管理资源,并在析构函数释放它,那么你几乎肯定需要落实或删除拷贝构造函数和拷贝赋值运算符,否则,你可以用两个对象最终都试图释放相同的资源。 – 2013-04-28 14:41:17

回答

2
cBuffer *buf; 
    foo() 
    { 
    buf = new cBuffer(gSize, oDist, Mode); 
    } 

你需要调用

delete buf; 

既然你明确要求new

0

class foo会导致你的泄漏,因为你永远不会删除动态分配的cBuffer。解决方案很简单:在这里完全不需要动态分配。

class foo { 
    cBuffer buf; // An object, not a pointer 
    foo() : buf(gSize, oDist, Mode) {} 
}; 

更一般地,当你需要动态分配,要小心,你总是deletenew。最可靠的方法是使用容器和智能指针等RAII类型为您管理所有动态资源。

+0

为什么我用指针的原因是这里讨论http://stackoverflow.com/questions/15922760/creating-an-object-in-the-constructor-or-an-init-function – mahmood 2013-04-28 14:53:40

+0

@mahmood:我没有看到指针的任何讨论那里,只是一些不好的建议告诉你使用指针,当你不需要,还有一些更好的建议,告诉你不要。 – 2013-04-28 14:54:47