[英]C++, copy constructor confusion
说我创建了一个自定义Array类,并具有以下构造函数:
Array::Array(size_t size)
{
mySize = size;
//myData is of type int*
myData = new int[mySize]; // this stuff is allocated on a heap
}
据我所知,在这种情况下,默认的复制构造函数将这样实现:
Array::Array(Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
最后,说我的main.cpp文件中有以下代码
int main()
{
Array a(1);
Array b(a); //copy constructor is invoked
}
我期望的是由于删除了指向空闲存储内存的myData指针而导致的内存泄漏,但是我遇到以下运行时错误:
*** glibc detected *** ./main.out: double free or corruption (fasttop): 0x086ad008 ***
为什么? 似乎〜Array()会以某种方式自动释放分配在堆上的内存-但这对我来说很不直观。 也许我缺少什么?
更新:
class Array{
private:
size_t mySize;
int *myData;
...
更新2:
main.cpp:
#include <iostream>
#include "array.h"
int main()
{
Array a(1);
Array b(a);
}
array.h:
#ifndef ARRAY_H_
#define ARRAY_H_
#include <stddef.h>
class Array{
private:
size_t mySize;
int *myData;
public:
Array(size_t size);
~Array();
void set(int i,int val);
int get(int i);
size_t getSize();
};
#endif
array.cpp:
#include "array.h"
Array::Array(size_t size)
{
mySize = size;
myData = new int[mySize];
}
Array::~Array()
{
delete[] myData;
}
void Array::set(int i, int val)
{
if(i>=0 && i<mySize)
myData[i] = val;
}
int Array::get(int i)
{
if(i>=0 && i<mySize)
return myData[i];
else return -1;
}
size_t Array::getSize()
{
return mySize;
}
我认为在你的毁灭者中
Array::~Array(void)
{
delete [] myData; //points to the same memory on the heap
}
问题是双重免费
例:
int main()
{
Array a(1); // here a.myData = 0x12345678
Array b(a); //copy constructor is invoked // here b.myData = 0x12345678
// pop stack (call destroy of object)
// delete b.myData
// delete a.myData already delete
}
双人免费
编辑:为您的复制构造const
使用const
因为您不修改a。
Array::Array(const Array& a)
{
mySize = a.mySize;
myData = a.myData; //points to the same memory on the heap
}
祝好运 !
所以...尽管您提出了要求,但事实证明您确实要删除析构函数中的数组,并且副本构造函数是浅表副本,因此您将获得两次删除。 简单。
Array::~Array()
{
delete[] myData;
}
由于这是一个动态数组,因此它应该拥有数据,因此您可以在析构函数中删除,但是您需要在复制构造函数和赋值运算符中“深化”副本。 见规则三 。
您的副本是浅表副本,因此, 如果您有释放内存的析构函数,则每个对象都会尝试删除相同的内存。
你不必做一个浅拷贝。 您可以编写自己的显式副本构造函数,将实际数据复制到新分配的数组中。
我喜欢Google关于禁用复制和赋值构造函数的建议,而更喜欢显式的CopyFrom()
方法。
“双重释放”表示已将相同的指针两次赋予delete[]
。 因为在您的析构函数中(大概是)它在对象a
和b
都为delete[]
-ed。 实际解决方案:使用std::vector
,不要与原始数组等混淆。
我认为您的析构函数(从数组'a'和'b')正在尝试释放相同的内存(双倍释放)。 也许您应该在释放之前检查myData。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.