C ++:push_back(new Object())内存泄漏?

时间:2010-11-24 20:18:17

标签: c++ memory new-operator memory-leaks

以下C ++代码是否存在内存泄漏?

list.push_back(new String("hi"));

据我了解,来自任何std集合/容器的push_back总是复制。因此,如果复制新字符串,没有什么可以删除新的字符串吗?因为在push_back之后没有引用它...

我在这里是对还是错?

感谢。

JBU

编辑:我认为我错了,因为new会返回一个指针......我们总是会有指针能够删除新的字符串

7 个答案:

答案 0 :(得分:8)

是的,但不是你想的原因。

根据list的定义和初始化方式,push_back可能会抛出异常。如果是,则从new返回的指针将丢失,永远不会被释放。

但假设push_back成功返回,它会存储new返回的指针的副本,因此我们可以稍后通过调用该副本上的delete来释放内存,因此没有内存只要您 正确地呼叫delete,就会泄露。

答案 1 :(得分:6)

不,向量存储指针,副本由指针组成。您可以在以后随时删除该对象。

(如果语句碰巧抛出异常并且你没有正确捕获并处理它,你可能会泄漏。这就是为什么你可以考虑使用智能指针。)

答案 2 :(得分:4)

如果我看到这段代码,我会非常怀疑内存泄漏是否可能。从表面上看,它似乎是将已分配的String*添加到list<String*>中。根据我的经验,通常会出现错误的错误处理代码,这些代码无法正常释放分配的内存。

虽然在许多情况下这很危险,但它不一定是内存泄漏。请考虑以下示例:

class Container {
  ~Container() {
    std::list<String*>::iterator it = list.begin();
    while (it != list.end()) {
      delete *it;
      it++;
    }
  }

  void SomeMethod() {
    ...
    list.push_back(new String("hi"));
  }

  std::list<String*> list;
}

在此代码中没有泄漏,因为包含类负责分配的内存,并将在析构函数中释放它。

修改

aschepler指出,如果push_back方法抛出异常,仍然存在泄漏。

答案 3 :(得分:1)

你是对的,只要在从列表中删除字符串时没有删除字符串。

答案 4 :(得分:1)

是的,这是一个内存泄漏,你会以某种方式删除包含的指针。

实现这一目标的最佳方法是使用智能指针。例如,Boost的shared_ptr或C ++ 0x的shared_ptr。

答案 5 :(得分:0)

没有

您可以通过执行以下操作删除对象:

delete list[i];
list.erase(list.begin() + i);

或清除整个清单:

for (unsigned int i = 0; i < list.size(); ++i)
{
  delete list[i];
}
list.clear();

答案 6 :(得分:0)

list.push_back(new String("hi"));

为什么要首先分配动态字符串?除非你想通过改变字符串(这很不寻常)在程序的不同部分之间进行通信,否则摆脱指针:

std::list<std::string> list;         // note: no pointer!
list.push_back(std::string("hi"));   // explicitly create temporary
list.push_back("hi");                // alternative: rely on coercion