内存分配不当?

时间:2014-02-21 14:34:59

标签: c++ visual-studio-2010

在测试我的代码时,我一直都会遇到有关使用delete的错误,因为我的类的测试表指出在使用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

3 个答案:

答案 0 :(得分:3)

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

你的拷贝构造函数在哪里?复制赋值运算符?您可能想了解the rule of three

答案 1 :(得分:2)

你可能遇到了这个问题,因为你不遵守三个规则 - 你需要一个复制构造函数和一个赋值操作符,在你的类中执行深层复制。

如果您执行类似

的操作
IntVector x(IntVector(10));

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

答案 2 :(得分:0)

除了违规规则外,您还试图在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实际上不是您的容量时)。