在具有向量的类构造函数中进行析构函数调用



我有以下类,它只是包装一个数组,并使用构造函数向其添加一些元素:

class myArray {
public:
myArray();
myArray(int a, int b);
myArray(int a, int b, int c);
myArray(myArray&& emplace);
~myArray();
int& operator [](int id);
private:
int *data;
};
myArray::myArray() {
data = new int[1];
data[0] = 0;
}
myArray::myArray(int a, int b) {
data = new int[3];
data[0] = 0;
data[1] = a;
data[2] = b;
}
myArray::myArray(int a, int b, int c) {
data = new int[4];
data[0] = 0;
data[1] = a;
data[2] = b;
data[3] = c;
}
myArray::~myArray() {
std::cout << "Destructor"<<std::endl;
delete[] data;
}
int& myArray::operator [](int id) {
return data[id];
}
myArray::myArray(myArray&& emplace) : data(std::move(emplace.data)) {}

此外,我有一个第二个类,它包含第一个类(myArray(的元素向量。

class Queue {
public:
Queue();
private:
std::vector<myArray> _queue;
};
Queue::Queue {
_queue.reserve(1000);
for(int a = 0; a < 10; a++)
for(int b = 0; b < 10; b++)
for(int c = 0; c < 10; c++)
_queue.emplace_back(a,b,c);
}

我的问题是:为什么在队列构造函数的末尾为 myArray 元素调用析构函数?队列对象在我的主程序中仍然处于活动状态,但 myArray 的析构函数释放了分配的内存,因此我得到了分段错误。

有没有办法避免调用析构函数,或者直到 Queue 对象生存期结束时才调用它?

移动构造函数不会在移出对象上将data设置为 null,因此当移自对象被销毁时,它将尝试释放数据。

如果你有 c++14,你可以使用std::exchange来实现这一点:

myArray::myArray(myArray&& emplace)
: data{std::exchange(emplace.data, nullptr)})
{}

否则,您需要执行以下操作:

myArray::myArray(myArray&& emplace)
: data{emplace.data)
{
emplace.data = nullptr;
}

移动构造函数将由std::vector调用时调用,因为它会重新分配以增加其容量,当您调用emplace_back时。执行类似于以下步骤的操作:

  1. 分配新内存以容纳元素
  2. 使用在新内存中放置新元素从先前内存中的元素移动构造
  3. 销毁上一个内存中的元素
  4. 释放以前的内存

最新更新