如果我像这样声明类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
可以避免所有的麻烦。