我有一个包含指针的类,该类不会继承任何内容
class MyClass
{
public:
MyClass();
~MyClass();
private:
//i have pointers here
};
MyClass::~MyClass()
{
print("destroyed..");
}
现在我必须将此类用作向量中的指针,如下所示:
vector<MyClass*> classes;
在这里推送一些类但是当我删除一个元素时:
classes.remove(index);
析构函数没有被调用,我认为我有内存泄漏 那么如何让它调用析构函数
答案 0 :(得分:3)
当指针被移除或清除时,指针向量对delete
指针不起任何作用。向量无法知道指针是否是动态分配的。致电delete
是不可能的。
您需要在指针上调用delete
,如果,并在必要时调用。您的问题中没有足够的细节来确定是否有必要(您没有显示指向的对象是如何分配的)。但是,由于您声称存在内存泄漏,这可能表明它们是动态分配的。直接的解决方案是调用delete:
delete *it;
classes.erase(it); // vector has no remove member function
更安全的解决方案是存储唯一的所有权智能指针,例如std::unique_ptr<MyClass>
。标准库还为共享和弱所有权提供智能指针。请参阅Smart Pointers。
以上所有假设您确实需要存储指针。通常,存储值更安全,更清晰:
std::vector<MyClass> classes; // but don't call it "classes". A vector stores objects.
答案 1 :(得分:2)
这就是为什么你应该避免在第一时间使用std::vector<MyClass*>
的原因之一。有一个丑陋的内存管理与它连接,它不会像classes.remove(index);
基本上,对于每个new
,必须调用delete
,并且对于每个new[]
,必须调用delete[]
,无论您是否将此指针用作局部变量或者你把它放到矢量中:
vector<MyClass*> vec;
vec.push_back(new MyClass()); // <-- object has been created
...
delete classes[index]; // <-- object shall be destructed
// the delete call will automatically invoke the destructor if needed
...
// now you can remove the dangling pointer from the vector
请注意,一旦对象被破坏,对此对象的任何(旧)引用都是无效的,并且尝试使用此类引用(悬空指针)访问此对象将产生未定义的行为。
答案 2 :(得分:1)
首先,std::vector
没有remove
,您可能意味着erase
。
其次,您需要在删除的内容上手动调用delete
:
vector<MyClass*> classes;
auto iter = <iterator to index to remove>;
delete *iter;;
classes.erase(iter);
或者,为了避免这些痛苦,请使用std::unique_ptr<MyClass>
。
答案 3 :(得分:0)
您必须在应用程序退出之前或从vector
移除类对象后手动删除指针。
// Delete all
vector<MyClass*>::iterator it = classes.begin();
while (it != classes.end()) {
delete *it;
it = classes.erase(it);
}
提示:从不添加堆栈构造的指针,如下所示:
MyClass m;
classes.push_back(&m);
编辑:正如其他成员所建议的那样,更好的解决方案是:
MyClass m(/* ... */);
vector<MyClass> classes;
classes.push_back(m);
但请注意,您必须正确实现复制构造函数,尤其是当您的类具有使用new创建的指针数据成员时。
答案 4 :(得分:0)
在从向量中移除之前,创建一个指向孔MyClass *指针的临时指针。
vector<MyClass*> classes;
//push some classes in here but
//when i remove an element
MyClass* temp = classes[index];
classes.remove(index);
// call delete temp; if you want to call the destructor thus avoid memory leak.
delete temp;
为了避免内存泄漏,请记住永远不要失去对堆对象的控制,在对象释放之前始终保持指针或对它的引用。
答案 5 :(得分:0)
目前还不清楚谁负责管理classes
内指针所指向的对象的生命周期。您是否已将new
指针推入其中,或者您是否已推送自动存储对象的地址?
如果您已完成前者,则必须先手动delete
指针才能将其删除。否则,如果你已经完成了后者,那么你可以保持原样,只是让指向对象在离开各自的范围时自行销毁。如果你有混合的new
ed和非new
指针,其可能性并不像你想象的那么遥远,那么你肯定是该死的,不明确的行为让恶魔飞出你的鼻子。
这些涉及指针的情况非常模糊,通常建议不要使用指针,并使std::vector
存储普通对象,这使得对象生命周期管理变得更加简单并且做出声明只是为自己说话。
vector<MyClass> classes; // Do this instead
答案 6 :(得分:0)
您似乎希望自己的向量成为项目的管理者
看一下boost :: ptr_vector类
它基本上是std :: vector类的包装器
您声明此向量是这些指针的“持有者”,如果您从这些容器中删除它们,则希望删除它们。
#include <boost/ptr_container/ptr_vector.hpp>
...
boost::ptr_vector<MyClass> myClassContainer;
myClassContainer.push_back(new MyClass());
myClassContainer.clear(); // will call delete on every stored object!