以下C ++代码是否存在内存泄漏?
list.push_back(new String("hi"));
据我了解,来自任何std集合/容器的push_back总是复制。因此,如果复制新字符串,没有什么可以删除新的字符串吗?因为在push_back之后没有引用它...
我在这里是对还是错?
感谢。
JBU
编辑:我认为我错了,因为new会返回一个指针......我们总是会有指针能够删除新的字符串
答案 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