这会导致C++中的内存泄漏吗?

tun*_*nuz 6 c++ pointers memory-leaks memory-management reference

我对C++内存管理有疑问,这显然与引用和指针有关.假设我有Class一个方法类my_method:

OtherClass& Class::my_method( ... ) {
    OtherClass* other_object = new OtherClass( ... );
    return *other_object;
}
Run Code Online (Sandbox Code Playgroud)

同时在附近的一段代码中:

{
    Class m( ... );
    OtherClass n;
    n = m.my_method( ... );
}
Run Code Online (Sandbox Code Playgroud)

所以,我知道有一个关于指针的一般规则(〜"任何新编辑,必须删除-d")以避免内存泄漏.但基本上我正在引用我的堆分配对象,所以当n超出范围时,不应该调用OtherClass的析构函数,从而释放之前由other_object指向的内存?所以最后真正的问题是:这会导致内存泄漏吗?

谢谢.

Ada*_*wes 12

是的,这会导致内存泄漏.

你要做的是,在return语句中,取消引用你创建的新对象.编译器将在返回时调用赋值运算符,并将新对象的CONTENTS复制到调用方法中指定的对象.

新对象将保留在堆上,并且其指针从堆栈中清除,从而产生内存泄漏.

为什么不返回指针并以这种方式管理它?


CB *_*ley 6

很明显,您希望将新对象返回给调用者,而不需要保留任何引用.为此,最简单的方法是按值返回对象.

OtherClass Class::my_method( ... ) {
    return OtherClass( ... );
}
Run Code Online (Sandbox Code Playgroud)

然后在调用代码中,您可以像这样构造新对象.

{
    Class m( ... );
    OtherClass n( m.mymethod( ... ) );
}
Run Code Online (Sandbox Code Playgroud)

这避免了任何担心返回对temporaries的引用或要求客户端管理器删除返回的指针.请注意,这确实需要您的对象是可复制的,但它是一个合法且通常实现的优化,以便在按值返回时避免使用该副本.

如果需要共享所有权,或者对象的生命周期超出调用函数的范围,则只需要考虑共享指针或类似指针.在后一种情况下,您可以将此决定留给客户端,并仍然按值返回.

例如

{
    Class m( ... );

    // Trust me I know what I'm doing, I'll delete this object later...
    OtherClass* n = new OtherClass( m.mymethod( ... ) );
}
Run Code Online (Sandbox Code Playgroud)


pet*_*hen 5

在C++中调用析构函数并释放内存是两回事.

delete它们都会调用析构函数并释放内存.delete[]调用析构函数以获取分配的元素数,然后释放内存.

当OtherClass超出范围时,将调用析构函数,但不释放内存.


作为一个建议,当你觉得你已经完全理解了C++中的指针时,请研究智能指针,例如使用智能指针来简化C++中的内存管理生活.(例如,请参阅此处的文章以获得介绍)