检测到堆损坏 - 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);
此行调用:
- A的复制构造函数,这里:A temp = A(size); 问题是,这创建了一个浅拷贝,因为它使用了默认的拷贝构造函数,我们在 class 中有一个指针,它需要一个深拷贝!
- A 的参数化构造函数,此处:A(size);
- 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成员,否则无法实现所需的复制功能。
以下代码导致断言错误。此外,警告错误消息指示检测到堆损坏。
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);
此行调用:
- A的复制构造函数,这里:A temp = A(size); 问题是,这创建了一个浅拷贝,因为它使用了默认的拷贝构造函数,我们在 class 中有一个指针,它需要一个深拷贝!
- A 的参数化构造函数,此处:A(size);
- 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成员,否则无法实现所需的复制功能。