我有一个定义为
的方法class1* class1::create(something)
{
class1* a = new class1(*this);
a->somemethod(something);
return a;
}
我将其他地方称为
class1* b = c::create(something);
所以我的问题是这个泄密记忆?如果不是为什么?
答案 0 :(得分:2)
是的,它会泄漏内存,除非调用者删除了b
。为什么?因为每次拨打new
都必须通过拨打delete
进行匹配。
请注意,这是一种危险且异常的不安全模式:最好返回管理自己资源的内容,而不是将其放在调用方上。你可以返回一个智能指针(std::unique_ptr
似乎是最合适的选项),或者只是按值返回class1
实例,而不是返回一个指针。
更多关于为什么它是一个麻烦的接口:一个指针在C ++中可以是很多东西。它可以是指向您可能需要或可能不需要删除的实例的指针。它可以是指向数组中第一个元素的指针,可以动态分配也可以不动态分配。因此,来电者必须知道是否要拨打delete
,delete[]
,或者根本不知道。这不考虑例外情况。如果在对class1::create
和delete b
的调用之间引发异常,则不会删除该对象。因此,使用管理自己资源的类型的重要性。
答案 1 :(得分:0)
如果最终你会打电话给delete b;
它不会泄漏,否则就会泄密。
答案 2 :(得分:0)
如果抛出无异常,它不会泄漏内存,也不会指向未定义的位置。也许您认为,class1
内create
的析构函数将被调用 - 事实并非如此,只有class1 *a
将从堆栈中删除,并且它是内置类型。 new class1
继续存在,直到您明确删除它为止。
但是当抛出异常时,可能会有内存泄漏,当class1
在其构造函数动态内存中分配时,仅依赖于它由析构函数释放 - 这不会发生,因为如果示例中的new class1
失败,class1
的析构函数不被调用! class1
失败时,只会从堆中删除已为new class1
成员变量分配的内存。
E.g。
class1* class1::create(something)
{
class1* a = new class1(*this);
a->somemethod(something);
return a;
}
和
class1 *b = 0;
try
{
b = c::create(something);
delete b;
}
catch(...)
{
delete b; // allright, no leak?
}
不保证无泄漏,如果class1
看起来是像这样
class1
{
int huge_var1[x][y][z];
int huge_var2[x][y][z];
int *huge_var3;
public:
class1 (const class1 &c)
{
// bla bla bla
huge_var3 = new int [x*y*z];
}
~class1 ()
{
delete huge_var3;
}
// bla bla bla
};
当您的new class1
失败时,huge_var1
和huge_var2
将从堆中释放,而不是huge_var3
指向的块。