这被认为是内存泄漏吗?

Gra*_*Guy 3 c++ memory-management

假设你有一个这样的简单类:

class foo{
private:
    int* mData;
    int  mSize;
public:
    foo(int size){
        mSize = size;
        mData = new int [mSize];
    }
    ~foo() {
        mSize = 0;
        delete [] mData;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后在主要内部你做:

int main () {
    static int HUGE = 100000000;
    foo a(HUGE);
    // do something useful with a
    // .
    // .
    // .
    // Now I'm done with a; I do not need it anymore ...
    foo b(HUGE);
    // do something useful with b
    // Ok we are done with b
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到a的那样,之后不再需要b,但由于它是在堆栈上创建的,因此在程序结束之前不会调用析构函数.现在,我知道这与分配new和忘记呼叫不同delete,但这仍然浪费记忆.你认为这是"内存泄漏"还是只是一个糟糕的编程?

另外,你会如何避免这样的情况?一种方法是在不再需要对象时手动调用析构函数,但是,除了看起来丑陋和不熟悉之外,你会遇到麻烦,double free除非你将析构函数改为:

foo::~foo(){
    if (mData != NULL){
        delete [] mData;
        mData = NULL;
        mSize = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是a在堆上创建via foo *pa = new foo (HUGE),然后delete pa在不再需要该对象时调用.这有效,但存在引入另一个可能的内存泄漏的危险(如果忘记调用delete pa).

有没有更好的方法摆脱不需要的对象?

Dar*_*con 10

当对象超出范围时,将调用析构函数.C++允许函数体内的任意范围.用这种方式写你的主要功能:

int main () {
    static int HUGE = 100000000;

    {
        foo a(HUGE);
        // do something useful with a
        // Now I'm done with a; I do not need it anymore ...
    }

    {
        foo b(HUGE);
        // do something useful with b
        // Ok we are done with b
    }
    // etc.
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我看到你的例子是简化的,但在真正的程序中,不要忘记

  • 实现适当的复制构造函数和operator=for foo
  • 为私有拷贝构造函数添加声明,operator=因此无法调用它.