检测到堆损坏 - class 带有指针

Heap Corruption Detected - class with pointers

以下代码导致断言错误。此外,警告错误消息指示检测到堆损坏。

class A {
    int* a; // dynamic array of ints
    A() {};
    A(int size) {
        a = new int[size]; 
    }
    ~A() {
        delete [] a;
        a = nullptr;
    }
}

*** in code somewhere ***
int size = 5;
A temp = A(size);

错误原因是:
A temp = A(size);
此行调用:

  1. A的复制构造函数,这里:A temp = A(size); 问题是,这创建了一个浅拷贝,因为它使用了默认的拷贝构造函数,我们在 class 中有一个指针,它需要一个深拷贝!
  2. A 的参数化构造函数,此处:A(size);
  3. A 的 析构函数,它将删除由 A temp 创建的指针并将其置空。

然后当 temp 变量超出范围时,它的 Destructor 将被再次调用 ,从而导致断言失败。

Solutions:

1. A temp(size);
instead of A temp = A(size);

this will only call the parametrized constructor.
or
2. Overwrite the default copy constructor to create a deep copy!

Another correction by Marco Costa
It is better to initialize a to nullptr in the default constructor.

Another correction by user4581301
Destructor should check, if a is a nullptr, before deleting.

Additional readings:
1. Why aren't pointers initialized with NULL by default?
2. Rule-of-Three becomes Rule-of-Five with C++11? suggested by Chad
3. scalar deleting destructor issue suggested by Chad

正如其他人所说,您需要遵循 3(或 5)的规则。

但是,你的class还有一个问题,那就是你没有记录元素个数。如果您想正确实现这些功能,这是必不可少的。没有标准的方法来检索您用于调用 new[] 的项目数量,因此您需要将此尺寸值记录为成员。

class A {
    int* a; 
    int aSize;  // records the number of elements.
    A() : aSize(0), a(nullptr) {}
    A(int size) : aSize(size) 
    { a = new int[size]; }

//...
};

您需要在您的class中添加size成员,否则无法实现所需的复制功能。