首先我动态分配一个对象:
Object* someObject = new Object();
然后我将这个指针的地址插入到一个向量中:
std::vector<Object**> someVector0;
someVector0.push_back(&someObject);
然后我把居住在
someVector0
的一个地址的地址插入到另一个vector中:
std::vector<Object***> someVector1;
someVector1.push_back(&someVector0[0]);
最后我将上述
someVector1
的地址插入到另一个向量中:
std::vector<std::vector<Object***>*> someVector2;
someVector2.push_back(&someVector1);
然后我使用获得的向量,现在我需要释放分配的内存:
//Do some stuff
//Free memory
for (int i = 0; i < someVector2.size(); i++) {
for (int j = 0; j < (*someVector2[i]).size(); j++) {
delete *(*(*someVector2[i])[j]);
delete *(*someVector2[i])[j];
delete (*someVector2[i])[j];
}
delete someVector2[i];
}
我曾怀疑这段代码足以解除分配,但是,我在解除分配时遇到了一些问题。我怀疑我可能取消了对
nullptr
的引用,但我想不出别的,我删除指针的方式会不会有错误?
注意:这是我在一个更大规模的程序中遇到的问题的简化版本,前面提到的向量都不是不必要的,我不想处理任何副本,也不要改变向量的类型。
对于单个元素,您调用了
new
一次,但 delete
调用了 4 次。那是错误的。你只能delete
你用new
创建的东西,一旦删除就不能再删除它。
对于初学者,你应该重新设计你的代码,因为它非常混乱和不清楚。
由于
Object
类型的每个对象只为每个运算符动态分配一次new
你只需要调用一个运算符delete
,
这是一个演示程序,展示了它是如何完成的。
#include <iostream>
#include <vector>
struct Object
{
int i;
~Object()
{
std::cout << "deleting object " << i << '\n';
}
};
int main()
{
std::vector<Object **> someVector;
Object *p_obj1 = new Object{ 1 };
Object *p_obj2 = new Object{ 2 };
someVector.push_back( &p_obj1 );
someVector.push_back( &p_obj2 );
std::vector<Object ***> someVector1;
for (auto &p : someVector)
{
someVector1.push_back( &p );
}
std::vector<std::vector<Object ***> *> someVector2;
someVector2.push_back( &someVector1 );
for (const auto p_vector1 : someVector2)
{
for (auto ppp : *p_vector1)
{
delete **ppp;
}
}
}
程序输出为
deleting object 1
deleting object 2
因为向量 someVector2 包含指向向量的指针,所以这个范围基于 for 循环
for (const auto p_vector1 : someVector2)
提供存储在指针类型向量中的每个元素
std::vector<Object ***> *
.
基于for循环取消引用此范围内的指针
for (auto ppp : *p_vector1)
你会得到指针类型的元素
Object ***
。因此,要释放 Object 类型的对象,您需要通过两次取消引用元素来获取指向它的指针
delete **ppp;