答案 0 :(得分:4)
使用new的规则非常简单:new
返回的指针必须在某些时候被某人删除,代码中的某处。如果new
返回的指针丢失,遗忘或丢弃,那么就会出现内存泄漏,这很糟糕。
因此,如果你new
一些内存而没有将它永久存储在任何地方而返回,那么你就会泄露内存。因此,如果您不打算删除它,那么指针必须存储在某种长期存储(类的成员,静态变量等)中,或者必须返回它以便其他人可以删除它
或者,你可以使用boost :: shared_ptr并停止关心(大部分)这个。
答案 1 :(得分:4)
它不必显式返回新创建的对象,但它应该以某种方式将其传递给其他东西。可能的情况包括:
示例:
class Foo {
private:
Baz* baz;
public:
Foo() : baz(0) { }
void create_bar() { baz = new Baz(); }
~Foo() { delete baz; }
};
示例:
void foo() {
// assuming bar lives in the global scope
bar.baz = new Baz();
}
void foo2(Bar& bar) {
bar.baz = new Baz();
// or, better:
bar.setBaz(new Baz());
}
示例:
std::auto_ptr<Baz> foo() {
return new Baz();
}
示例:
void foo(Bar* bar) {
bar->dostuff();
delete bar;
}
void baz() {
Bar* bar = new Bar();
foo(bar);
}
答案 2 :(得分:1)
如果函数使用new
创建资源并且没有将指向该资源的指针传递回任何东西,那么它必须删除该资源,否则它将永远不会被清除,从而导致内存泄漏。
答案 3 :(得分:1)
不,如果函数的目的是实例化一些数据并将其移交给其他对象。游戏行业的一个(假设的)例子:
void AddProjectileAtPoint(int x, int y)
{
Projectile *p = new Projectile(x, y);
mProjectileManager->Add(p); //"mProjectileManager"'s job is to hold all projectiles and update them every frame...
}
在这种情况下,明确的目的是创建一个表示某些数据的新对象,并将其存储在某处以供以后使用。
显然,在某些时候需要匹配delete
,而不是在new
发生的函数内。只要有明确定义的程序将管理new
'内存的责任传递给其他组件,就可以了。
在这种情况下,结构是“射弹管理器”对所有射弹负责,并在需要时保持它们存活,并在适当时清理记忆。
答案 4 :(得分:1)
如果在函数中使用new
分配内存,并且该函数(或静态)之外的内存不可访问,则需要在函数存在之前释放它。在这种情况下,我建议您使用std::auto_ptr
或boost::scoped_ptr
,因为当函数退出时,它会为您调用delete
。即使抛出异常。
答案 5 :(得分:0)
不一定,如果它正在分配静态对象(例如,实现单例模式)。
答案 6 :(得分:0)
不,不一定。您可能已在其他位置存储了指向动态分配对象的指针。例如对于某些class
A
:
A* ptr = NULL;
void foo() {
ptr = new A();
}
你 应该在某个地方delete ptr
,但不一定要在foo()
。
另一方面,如果你没有把它存放在其他任何地方:
void foo() {
A* ptr = new A();
}
然后,是的,这是内存泄漏。你永远不能回到指针去做delete ptr
!
请注意,最好使用shared_ptr
或unique_ptr
之类的“智能指针”实现为您处理这些内容。