这段愚蠢的代码已经花了我2个小时,我不知道为什么第一个元素的析构函数(大小为7的析构函数)没有被调用?分配的内存会new uint16_t[7]
怎样?
#include <iostream>
using namespace std;
struct Node
{
Node(uint16_t n) : p(new uint16_t[n]) {
cout<<"Constructed with size= "<<n<<", memory addr: "<<(p)<<endl;
for(uint16_t i=0; i<n; i++) p[i] = n;
}
~Node() {
cout<<"Destructor for p[0] = "<< *p <<" with memory addr: "<<p<<endl;
delete[] p;
}
uint16_t *p;
};
int main()
{
{
Node nd1(7);
{
nd1 = Node(3);
cout << "1st place holder" << endl;
}
cout << "2nd place holder" << endl;
}
return 0;
}
输出是
Constructed with size= 7, memory addr: 0x158cc20 Constructed with size= 3, memory addr: 0x158cc40 Destructor for p[0] = 3 with memory addr: 0x158cc40 1st place holder 2nd place holder Destructor for p[0] = 0 with memory addr: 0x158cc40 *** Error in `./a.out': double free or corruption (fasttop): 0x000000000158cc40 *** Aborted (core dumped)
这段代码:nd1 = Node(3);
不是您所期望的。
它不会取代nd1
与Node(3)
和杀老nd1
。
它的作用是创建一个新的临时节点实例Node(3)
,并将每个成员的值复制到中nd1
。因此,临时和nd1
包含指向同一地址的指针。那时,您泄漏了nd1
在程序开始时分配的内存,因为没有指针引用它,但是您没有删除它。
当临时对象死亡时,nd1
指向死内存。当nd1
运行它在第二析构函数}
,它删除同一指针再次因此你的错误。
要解决此问题,您必须实现所谓的5规则或零规则。
最简单的是零规则。只需使用unique_ptr
,销毁就会按预期进行:
struct Node
{
Node(uint16_t n) : p(std::make_unique<uint16_t[]>(n)) {
cout<<"Constructed with size= "<<n<<", memory addr: "<<(p)<<endl;
for(uint16_t i=0; i<n; i++) p[i] = n;
}
std::unique_ptr<uint16_t[]> p;
};
int main()
{
{
Node nd1(7);
{
nd1 = Node(3); // assignement destroys the old buffer
cout << "1st place holder" << endl;
}
cout << "2nd place holder" << endl;
}
return 0;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句