【问题标题】:when populating an std::vector by value, will dynamically allocated object pointers be deleted? [duplicate]按值填充 std::vector 时,会删除动态分配的对象指针吗? [复制]
【发布时间】:2012-12-24 00:13:12
【问题描述】:

可能重复:
Why does the use of ‘new’ cause memory leaks?

我对 STL 还很陌生,并且我读到通常保留对象向量而不是指向对象的指针向量是一种很好的做法。为了遵守该信条,我遇到了以下情况:

//Approach A
//dynamically allocates mem for DD_DungeonRoom object, returns a pointer to the block.
//then, presumably, copy-constructs the de-referenced DD_DungeonRoom as a 
//disparate DD_DungeonRoom object to be stored at the tail of the vector
//Probably causes memory leak due to the dynamically allocated mem block not being
//caught and explicitly deleted
mvLayoutArray.push_back(*(new DD_DungeonRoom()));

//Approach B
//same as A, but implemented in such a way that the dynamically allocated mem block
//tempRoom can be deleted after it is de-referenced and a disparate DD_DungeonRoom is
//copy-constructed into the vector
//obviously rather wasteful but should produce the vector of object values we want
DD_DungeonRoom* tempRoom = new DD_DungeonRoom();
mvLayoutArray.push_back(*(tempRoom));
delete tempRoom;

第一个问题:在方法 A 中,是否产生了内存泄漏?
第二个问题:假设A确实产生了内存泄漏,B解决了吗? 第三个问题:是否有(或者更有可能是“什么是”)更好的方法来将自定义类对象(例如,需要通过“new”或“malloc”进行动态分配)按值添加到向量中?

谢谢, CCJ

【问题讨论】:

标签: c++ pointers memory-leaks vector dynamic-allocation


【解决方案1】:

第一个问题:在方法 A 中,是否产生了内存泄漏?

是的。

第二个问题:假设 A 确实产生了内存泄漏,B 解决了吗?

是的,但这是一个愚蠢的解决方案。如果DD_DungeonRoom 的复制构造函数或vector::push_back 抛出异常,则不安全。

第三个问题:是否有(或更可能是“什么是”)更好的方法来 添加自定义类对象(例如,需要通过“新”进行动态分配 或 'malloc') 按值转换为向量?

C++ 中没有对象需要动态内存分配。只需将对象直接添加到调用构造函数的向量中,无需new

mvLayoutArray.push_back(DD_DungeonRoom());

更好的是,如果您的编译器支持该功能(它是 C++11 的新功能),将使用完全绕过任何副本的emplace_back,并直接在向量中构造您的对象。只需将与构造函数相同的参数传递给它。在我们的例子中,没有:

myLayoutArray.emplace_back();

【讨论】:

  • 嗯,我不知道 push_back() 是有效的语法。好吧,这简化并显着改善了问题!
  • @CCJ:是的,一旦你摆脱了 Java 的想法,C++ 就会变得更简单、更漂亮。
【解决方案2】:

方法 A 会导致泄漏,是的。 方法 B 没有,但由于您所做的只是在堆上分配一个对象,将一个副本放入向量中然后删除它,因此在这种情况下您也可以这样做:

DD_DungeonRoom tempRoom;
mvLayoutArray.push_back(tempRoom);

如果您希望析构函数随后立即运行,您可以选择在它周围做一个块以使局部变量超出范围。

此外,如果您对某些东西是否会泄漏内存感到好奇,有很多很好的工具可以实际尝试一下,看看会发生什么。 valgrind 是一个超级好用的例子。

【讨论】:

    【解决方案3】:

    如果您对 aproch A 的唯一问题是内存泄漏,为什么不使用 shared_ptr 的向量?

    【讨论】:

    • 因为它的开销对于他的情况来说是不必要的。
    • 比构造每个只复制到向量然后被销毁的开销更多?它取决于建造 DD_DungeonRoom 的大小或成本。还是?
    • shared_ptr 确实比我现在需要的复杂一点;显然方法 B 不是一个好的生产解决方案,而是用来澄清我的困惑。 @BenjaminLindley 的建议最适合我的情况。
    • 好的。现在我不确定,但是看看你是否可以从移动复制构造或 soo 中受益。
    猜你喜欢
    • 2011-07-23
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 2016-03-15
    • 2010-10-27
    • 1970-01-01
    相关资源
    最近更新 更多