内存分配不当

Improper de-allocation of memory?

本文关键字:分配 内存      更新时间:2023-10-16

在测试我的代码时,我经常收到有关使用删除的错误,因为我类的测试平台指出正在使用 new[] 分配的数组上调用 delete。 我在 ~IntVector 中删除了两个扩展函数,其中扩展函数扩展了容量,同时为动态分配的数组重新分配了内存。

如何正确使用删除来防止内存泄漏并解决此错误?

主文件

#include "IntVector.h"
#include <iostream>
#include <vector>
using namespace std;

IntVector::~IntVector(){
    delete[] data;
}
void IntVector::expand(){
    cap = cap * 2;
    int *data2 = data;
    data = new int[cap];
    data = data2;
    delete data2;
    delete[] data2;
}
void IntVector::expand(unsigned amount){
    cap = amount;
    int *data2 = data;
    data = new int[cap];
    data = data2;
    delete data2;
    delete[] data2;
}

页眉

#ifndef INTVECTOR_H
#define INTVECTOR_H
using namespace std;
class IntVector{
private:
    unsigned sz;
    unsigned cap;
    int *data;
private:
    void expand();
    void expand(unsigned amount);
};
#endif
使用

new[] 分配时,您必须使用 delete[] .您的expand函数使用普通delete。它还包含一些其他错误(重新分配指针、双重删除等)。

你的复制构造函数在哪里?复制赋值运算符?您可能想阅读有关三法则的信息。

您可能遇到了这个问题,因为您不遵守三法则 - 您需要类中执行深层复制的复制构造函数和赋值运算符。

如果你做类似的事情

IntVector x(IntVector(10));

您将在x中留下一个悬空的指针,因为当临时IntVector(10)超出范围时,原始指针将被取消分配。

除了存在冲突的规则之外,您还尝试在expand函数中删除变量两次:

void IntVector::expand()
{
    cap = cap * 2;
    int *data2 = data;
    data = new int[cap];
    data = data2;
    delete data2; // this should not be here!
    delete[] data2; // this will be a problem now!
}

您只能删除一次数据,如果您使用 new[] 创建了某些内容,则需要使用 delete[] 将其删除。

两个扩展函数应该看起来更像:

// copy-swap
void IntVector::expand()
{
    IntVector tmp;
    tmp.reserve(cap * 2);
    tmp.resize(sz);
    std::copy(data, data + sz, tmp.data);
    std::swap(*this, tmp);
}

// raw implementation
void IntVector::expand()
{
    unsigned int newCap = cap * 2;
    int* newData = new int[newCap];
    std::copy(data, data + sz, newData);
    delete [] data;
    data = newData;
    cap = newCap;
}
复制

交换版本将允许您重用其他函数(析构函数、复制赋值运算符),并且将更加异常安全。 在正确创建新数据元素之前,原始实现不应修改内部数据元素。 这可以防止new中可能引发的异常使您的向量处于错误状态(例如,当cap实际上不是您的容量时)。