gpt4 book ai didi

c++ - 内存泄漏;删除异常时引发

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:50:27 25 4
gpt4 key购买 nike

我正在编写一个可调整大小的数组类 (std::vector),作为练习,使用手动指针(因为我想在开始使用智能指针之前知道它们是如何工作的)。但是,Valgrind 报告 checkMax() 函数存在内存泄漏。

template <typename T>
class Array{
public:
Array() : len(0),maxLen(1){
array=new T[maxLen];
// ........
}
Array(unsigned length, T&content=0) : len(length),maxLen(length*2){
array=new T[maxLen];
//..............
}
~Array(){
//delete[] array;
}
//..............
void push_back(const T& content){
checkMax();
// do stuff...
}
private:
T* array;
unsigned int len;
unsigned int maxLen;
..
void checkMax(){
if(len==maxLen){
//allocate more memory for the array
maxLen*=2;
T*temp=new T[maxLen]; // ------------- MEMORY LEAK HERE -------------
for(unsigned int i=0; i<len; i++){
temp[i]=array[i];
}
delete [] array;
array=temp;
}
}
};

我在这里只发布了与内存相关的代码。

我不明白为什么 Valgrind 在指定行报告内存泄漏。在将旧数组内容复制到扩大后的数组后,我确实删除了旧数组,两行之后。

此外,如果我在析构函数中取消注释 delete[] 函数,我会得到一个异常 double free or corruption 并且 Valgrind 报告一个无效删除(暗示重新删除),所以我完全糊涂了。有什么想法吗?

编辑: 感谢您的早期回复!阅读评论后,我发现问题不在于我的类,而在于我调用的另一个函数以 Array 类作为参数。如果我删除对该函数的调用,并在类中添加删除调用,则不会发生内存泄漏。这是我的功能:

template <typename T>
void printContents(Array<T> ar){
for(unsigned int i=0; i<ar.size(); i++){
cout<<"Content at i in array = " << ar.at(i) << endl;
}
}

在阅读三规则(感谢 chris)和 Grizzly 发布的答案后,我现在明白了为什么 delete[] 无效。因为我没有重载复制构造函数,所以发生了浅复制,因此,我的数组指针被分配到ar中的指针,当ar超出范围时,调用了delete[],从而使我在主函数中的删除 无效 。因此,我得到了异常(exception)。如果我删除删除,那么数组显然会保持分配状态并导致内存泄漏。

感谢您的帮助,我认为 Grizzly 的回答是正确的。

最佳答案

您没有在析构函数中调用 delete[] 就会泄漏内存。这意味着当您最后一次在对象上调用 checkMax 时分配的数组(对象中的“最终”数组)永远不会被调用。所以要解决这个问题,你应该在析构函数中取消注释 delete[]

正如您所提到的,这会给您带来双重免费的问题。这是基于违反三的规则(在 C++03 中它是三的规则,在 C++11 中情况不那么明确,但对于这种情况,三的规则足以解决你的问题)。三原则基本上表明,当您定义自定义析构函数、复制构造函数或赋值运算符时,您需要定义所有这些。在这种情况下,您可能正在某处复制 Array。这意味着两个实例将包含相同的指针并尝试在析构函数中将其删除。对同一个指针调用 delete 两次是错误的。要解决该问题,您需要定义自定义复制构造函数和赋值操作,在其中执行数组的深度复制(分配新内存并将内容复制过来)。

除此之外,我个人建议从智能指针开始,只有在您更好地掌握 C++ 之后,才开始尝试手动内存管理。

关于c++ - 内存泄漏;删除异常时引发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16749860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com