使用for循环+delete删除堆上对象数组失效的问题修正
问题
我是一名C初学者,目前遇到堆内存释放问题:尝试通过for循环配合delete关键字(利用指针算术)删除堆上分配的ArrayClass对象数组,而非使用delete[] instance语句。但运行程序时,析构函数的输出未在控制台打印,程序直接终止,不执行std::cin.get()语句。仅使用delete[] instance时功能正常。我希望采用for循环+delete的方式,请问该方法在C中是否合法?如何修正错误?
#include <iostream> class ArrayClass { private: int *m_Arr; int i; public: int Size; ArrayClass() : Size(5), i(0), m_Arr(nullptr) { std::cout << "The constructor was called." << std::endl; } ~ArrayClass() { std::cout << "The destructor was called." << std::endl; delete[] m_Arr; } void InitArr() { m_Arr = new int[Size]; } void Setter(int &var) { *(m_Arr + i) = var; i++; } int *Getter() const { return m_Arr; } }; int main() { ArrayClass *instance = new ArrayClass[2]; std::cout << instance << std::endl; for (int j = 0; j < 2; j++) { (instance + j)->InitArr(); for (int i = 1; i <= (instance + j)->Size; i++) { (instance + j)->Setter(i); } int *Get = (instance + j)->Getter(); std::cout << "The numbers are:" << std::endl; for (int i = 0; i < (instance + j)->Size; i++) { std::cout << *(Get + i) << std::endl; } } for (int l = 0; l < 2; l++) { delete (instance + l); } std::cin.get(); return 0; }
回答
这种for循环+
delete的方式在C++中不合法:当使用new[]分配对象数组时,编译器会在数组内存的头部额外存储元素数量的元数据,供delete[]用来遍历调用每个对象的析构函数,再统一释放整块内存。直接用delete逐个删除数组元素指针,会破坏这块元数据,触发未定义行为——这就是程序直接终止、析构函数输出未打印的原因。若非要手动模拟
delete[]的行为(不推荐,标准方式更安全),需分两步操作:- 手动遍历数组,调用每个对象的析构函数
- 使用
operator delete[](而非delete关键字)释放整块内存
修改后的释放代码如下:
// 手动调用每个对象的析构函数,执行清理逻辑 for (int l = 0; l < 2; l++) { (instance + l)->~ArrayClass(); } // 释放new[]分配的整块内存,不触发额外析构调用 operator delete[](instance);
注意:虽然上述方法能实现预期效果,但强烈建议直接使用
delete[] instance——这是C++标准规定的new[]匹配释放方式,代码简洁且能避免手动操作带来的错误。
内容的提问来源于stack exchange,提问作者King Crows Schmétterling
相关产品推荐
相关产品推荐

