使用 RAII 替换最终块以释放内存
Using RAII to replace the finally block to free memory
我正在研究C++的RAII机制,它取代了Java的finally
。 我编写了以下代码来测试它:
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()
(时,它也不起作用。我应该执行哪些修复才能实现所需的操作?
这是因为您使用new Finally(arr)
创建的对象并没有真正在程序中被破坏。
你对对象的分配只会立即丢弃对象,导致内存泄漏,但更重要的是,它是在尝试和捕获的范围之外创建的。
要让它工作,你必须做一些类似的事情
try {
Finally f(arr);
foo(arr);
} catch (int e) {
cout << "Oh No!" << endl;
}
这将在 try 中f
创建一个新对象,然后在抛出异常时(以及如果没有抛出异常,则超出try
范围时(该对象将被销毁。
你假设C++作品喜欢Java。 它没有,所以你的代码中实际上有一些错误
声明
new Finally(arr);
动态分配一个Finally
,但它永远不会在你的代码中发布。 因此,永远不会调用其析构函数。
而是做
Finally some_name(arr);
这将在main()
结束时调用Finally
的析构函数,这将提供您期望的输出。
然而,第二件错误的事情是Finally
的析构函数delete (p)
给出未定义的行为,因为p
是new int [10]
的结果(在main()
年(。 要为代码提供明确定义的行为,请将delete (p)
更改为delete [] p
。
第三,通过上述两个修复程序,您没有使用 RAII。 RAII 的意思是"资源获取是初始化",这实际上不是您的代码所做的。 更好的形式是在构造函数中使用新表达式初始化p
Finally
并在析构函数中使用正确的delete
表达式发布它。
class Finally
{
private:
int* p;
public:
Finally() : p(new int [10])
{
cout << "constructor" << endl;
};
~Finally()
{
cout << "destructor" << endl;
delete [] p;
};
int *data() {return p;};
};
并将main()
的前两行替换为一行
Finally some_name;
和foo()
的呼唤
foo(some_name.data());
更一般地说,不要再假设C++像Java一样工作。 两种语言的工作方式不同。 如果你坚持像在 Java 中那样使用C++构造函数,你将编写出非常错误的C++代码。
- 如何在c++中释放内存
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- std::unordered_map析构函数不释放内存?
- 在C++中释放内存期间,迭代器与指针有何不同
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 释放内存(主题模板)时出现问题
- 使用后自动释放内存
- C++ 如何释放内存
- 从函数内对象的向量中释放内存
- C++ 在不释放内存的情况下调用析构函数
- 多个线程之间的获取-释放内存顺序
- C++ - 析构函数只是释放内存还是实际删除对象
- 使用 RAII 替换最终块以释放内存
- 如何通过带有指向基类的指针的删除运算符释放内存
- 代码中的"sprintf"用法是否需要释放内存?
- C++何时使用 delete[] 并正确释放内存?
- 为什么此获取和释放内存围栏不能给出一致的值?
- 抛出新表达式的参数子表达式时释放内存
- 在这种情况下,如何释放内存?
- 在 c++ 中应按什么顺序释放内存?