【问题标题】:How to delete dynamic allocated class object in list<T>?如何删除 list<T> 中动态分配的类对象?
【发布时间】:2019-07-09 00:16:37
【问题描述】:

我只是在函数内部创建如下 Coordi 对象列表。 Coordi 是我定义的类对象。

list<Coordi> LstOfCoordi;
for (int i = 0; i < 10; ++i)
{
    Coordi *tmp = new Coordi();
    LstOfCoordi.push_back(tmp);
} 

我想在程序终止之前将列表和每个对象释放到系统。

如果列表的每个元素都必须释放,如何处理?我尝试在下面的代码中使用删除它们中的每一个,但它产生了编译错误。

for (int i = 0; i < 10; ++i)
{
    myClass tmp = LstOfMyCalss.back();
    delete &tmp;
    LstOfMyClass.pop_back();
} 

所以,我想知道从列表中删除是否足够。 看下面的代码,每个元素都被分配了,当列表被销毁时,它们并没有被正确释放。

for (int i = 0; i < 10; ++i)
{
    //myClass tmp = LstOfMyCalss.back();
    //delete &tmp;
    LstOfMyClass.pop_back();
} 

请告诉我释放所有已分配对象的最佳方式。

【问题讨论】:

  • 1.不要使用 C 风格的指针,那么你就不必担心这些事情了。 2.myClass tmp =...; delete &amp;tmp; 始终是 UB。 3. 如果您真的需要代码方面的帮助,请提供minimal reproducible example。例如,我们不知道list 是什么。 (是std::list吗?是你自己实现的吗?是你在使用的其他第三方类吗?) 4. 如果遇到编译错误,请与我们分享。
  • 如果这是std::list,您的列表不存储指针,它存储原始值,并且根本不应该使用new。您的编译器应该拒绝此代码(因为您试图将Coordi* 存储在包含Coordilist 中)。最好的解决方案通常是根本不使用显式动态分配,而只是按值存储(在这种情况下不需要特殊清理;当列表被销毁时,它的内容会自动为您销毁)。
  • 我知道,在现代 C++ 中,我们可以使用可用的库在 &lt;memory&gt; 标头中使用智能指针,但是,人们声明:“不要使用原始或 C 样式指针”。我这样说是因为当我第一次学习 C++ 时没有智能指针,一切都是手动完成的,你必须了解内存、堆分配、指针算术、悬空指针和引用、内存管理、结构对齐、删除指针与删除指针数组、缓存和页面对齐等...
  • @Max Vollmer,感谢您的建议。这是第一次问。我会记住你在其他问题上所说的话。

标签: c++ list c++11


【解决方案1】:

编辑: 使用 std::list 创建对象列表的示例代码。

class MyClass {
public:
    std::list<Coordi> m_listCoordi;
}

//---creation of list of objects
for(int a = 0; a < numObjects; a++){
    m_listCoordi.push_back(Coordi());  //note: no 'new' is used.
}

//---destroying list of objects
m_listCoordi.clear();

使用 std::list 创建指向对象的指针列表的示例代码。

class MyClass {
public:
    std::list<Coordi*> m_listCoordi;  //<---note: now list of pointer
}

//---creation of list of objects
for(int a = 0; a < numObjects; a++){
    m_listCoordi.push_back(new Coordi());
}

//---destroying list of objects
for(int a = 0; a < numObjects; a++){
    delete m_listCoordi[a];  //note: an item in m_listCoordi is already a pointer.
}
m_listCoordi.clear();

我为一个混乱的答案道歉。我没有太多时间让它更干净更正式。无论如何,我希望它有所帮助。


上一个答案:

如果您的列表,例如std::vector&lt;YourClass*&gt;,则元素保存指针值。从您保存在列表中的指针值分配和取消分配内存块是您的责任。无论您分配/取消分配的方法是什么,都取决于您。只要确保您的代码不会产生内存泄漏。

//---deallocate all elements before clearing the list.
for(auto& pItem : LstOfMyClass){  
    //note: since LstOfMyClass is a list of pointer values, pItem is a pointer variable.
    delete pItem;
}
//---clear the list.
LstOfMyClass.clear();

如果LstOfMyClass 中的对象没有移动或列表没有增长或缩小,最好使用对象列表而不是指向对象的指针列表。有了这个,您不必担心分配和解除分配。如果列表变量被销毁,列表将为您执行此操作。

【讨论】:

  • OP 的列表可能是std::list,而不是std::vector,并且它包含的元素不是 指针。这回答了一个问题,但 OP 似乎对他们首先在做什么感到很困惑;我会坚持使用 cmets 弄清楚他们的意图。
  • 我打算以类似的方式回答,因为 OP 试图删除某些容器中不是指针的对象,但你打败了我!
  • 谢谢,这就是我想知道的。我在寻找自定义对象的示例,但大多数示例使用 std::list。感谢您的大力帮助。
猜你喜欢
  • 2014-05-19
  • 2012-11-06
  • 2018-12-16
  • 2011-07-23
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
相关资源
最近更新 更多