首页 > 解决方案 > 使用RAII替换finally块释放内存

问题描述

我正在研究C++ 中取代finallyJava 的 RAII 机制。我编写了以下代码来测试它:

void foo(int* arr) {
    cout << "A" << endl;
    throw 20;
    cout << "B" << endl;
}

class Finally {
private:
    int* p;
public:
    Finally(int* arr) {
        cout << "constructor" << endl;
        p = arr;
    }

    ~Finally() {
        cout << "destructor" << endl;
        delete(p);
    }
};

int main()
{
    int * arr = new int[10];
    new Finally(arr);
    try {
        foo(arr);
    } catch (int e) {
        cout << "Oh No!" << endl;
    }
    cout << "Done" << endl;
    return 0;
}

我想释放我使用的内存,arr所以我设置了一个新类Finally,它保存指向数组的指针,当它退出范围时,它应该调用析构函数并释放它。但输出是:

constructor
A
Oh No!
Done

没有调用析构函数。main当我将主体移动到其他一些 void 方法(如void foo())时,它也不起作用。我应该做些什么来实现所需的操作?

标签: c++raii

解决方案


那是因为你创建的对象new Finally(arr)并没有真正在你的程序中被破坏。

您对对象的分配只是立即将对象丢弃,导致内存泄漏,但更重要的是,它是在 try 和 catch 范围之外创建的。

为了让它工作,你必须做类似的事情

try {
    Finally f(arr);
    foo(arr);
} catch (int e) {
    cout << "Oh No!" << endl;
}

这将在 try 中创建一个新对象f,然后在抛出异常时(以及当它超出try如果没有抛出异常的范围时)将被破坏。


推荐阅读