C++:默认析构函数:它会删除成员指针指向的数组吗



如果我像这样声明类MyObj:

class MyObj: {
private:
uint8_t *arrayPtr;
public:
void makeArray();
}
void MyObj::makeArray() {
arrayPtr = new uint8_t [10];
}

然后我打电话给:

void func() {
MyObj testObj;
testObj.makeArray();
}

既然func已经运行并完成,testObj可以被忘记了,那么10字节数组会从堆栈中删除吗?或者我需要为MyObj创建一个显式析构函数来测试数组的存在并调用它的delete函数吗?

您不能在此代码段中调用delete

MyObj testObj;
testObj.makeArray();
delete testObj;

因为testObj不是由使用运算符new分配的内存地址分配的指针。

您需要在类定义中至少添加一个初始值设定项和析构函数

class MyObj {
private:
uint8_t *arrayPtr = nullptr;
public:
~MyObj() { delete [] arrayPtr; }
void makeArray();
};

请注意,要么将复制构造函数和复制赋值运算符定义为已删除,要么必须显式定义它们。

还要记住,函数makeArray是不安全的。如果用户第二次调用它,就会出现内存泄漏,因为之前分配的内存不会被删除。

并且您没有一个数组作为类的数据成员。你有一个指针。该指针将与包含该指针的对象一起从堆栈中释放。但是,如果不调用运算符delete[],则不会释放动态分配的数组。

不允许对具有自动存储持续时间的对象("在堆栈上"(调用delete。它会导致程序的未定义行为。

您必须根据从new(或new[](返回的指针值调用delete(或delete[](,而这永远不会自动完成。

因此,是的,您需要添加一个执行删除的析构函数,并且必须小心遵守0/3/5规则,这意味着您还需要编写具有正确语义的复制构造函数和赋值运算符。

使用std::vector<uint8_t>代替arrayPtr可以避免所有的麻烦。

最新更新