C++中怎么使用RAII防止资源泄露

发布时间:2021-07-30 16:15:03 作者:Leah
来源:亿速云 阅读:127

C++中怎么使用RAII防止资源泄露,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Reason(原因)

Leaks are typically unacceptable. Manual resource release is error-prone. RAII ("Resource Acquisition Is Initialization") is the simplest, most systematic way of preventing leaks.

资源泄露通常都是不可接受的。手动释放资源容易引发错误。RAII(“资源请求即初始化”)是防止泄露最简单,更加系统化的方式。

Example(示例)

void f1(int i)   // Bad: possible leak
{
   int* p = new int[12];
   // ...
   if (i < 17) throw Bad{"in f()", i};
   // ...
}

We could carefully release the resource before the throw:

在抛出异常之前,我们必须小心地释放资源:

void f2(int i)   // Clumsy and error-prone: explicit release
{
   int* p = new int[12];
   // ...
   if (i < 17) {
       delete[] p;
       throw Bad{"in f()", i};
   }
   // ...
}

This is verbose. In larger code with multiple possible throws explicit releases become repetitive and error-prone.

代码冗长。在更大规模的,存在更多的抛出异常的可能性的代码中,显示释放资源会更加繁复和易错。

void f3(int i)   // OK: resource management done by a handle (but see below)
{
   auto p = make_unique<int[]>(12);
   // ...
   if (i < 17) throw Bad{"in f()", i};
   // ...
}

Note that this works even when the throw is implicit because it happened in a called function:

需要注意的是,即使是隐式的抛出动作(因为它在调用的函数中发生),这段代码仍然可以起作用。

void f4(int i)   // OK: resource management done by a handle (but see below)
{
   auto p = make_unique<int[]>(12);
   // ...
   helper(i);   // may throw
   // ...
}

Unless you really need pointer semantics, use a local resource object:

除非你真的需要指针语义,否则使用一个局部的资源对象:

void f5(int i)   // OK: resource management done by local object
{
   vector<int> v(12);
   // ...
   helper(i);   // may throw
   // ...
}

That's even simpler and safer, and often more efficient.

这样更简单,更安全,甚至更高效。

Note(注意)

If there is no obvious resource handle and for some reason defining a proper RAII object/handle is infeasible, as a last resort, cleanup actions can be represented by a final_action object.

如果没有明显的资源句柄而且由于某种原因定义适当的RAII对象/句柄不可行,作为最有手段,可以通过一个final_actrion对象实现清理动作。

Note(注意)

But what do we do if we are writing a program where exceptions cannot be used? First challenge that assumption; there are many anti-exceptions myths around. We know of only a few good reasons:

但是,如果我们在写一个程序而无法使用异常处理时,我们应该做什么?首先挑战这个假设;存在很多反对使用异常的神话。我们只知道很少几个是正当理由:

Only the first of these reasons is fundamental, so whenever possible, use exceptions to implement RAII, or design your RAII objects to never fail. When exceptions cannot be used, simulate RAII. That is, systematically check that objects are valid after construction and still release all resources in the destructor. One strategy is to add a valid() operation to every resource handle:

这些原因中只有第一个是根本性的,因此只要可能就使用异常来实现RAII,或者设计自己的RAII对象来保证永远不失败。如果无法使用异常,就模仿RAII的动作。即系统化的检查对象被构建之后的有效性和析构时会释放所有资源。一个策略是为每一个资源句柄增加一个valid操作。

void f()
{
   vector<string> vs(100);   // not std::vector: valid() added
   if (!vs.valid()) {
       // handle error or exit
   }

   ifstream fs("foo");   // not std::ifstream: valid() added
   if (!fs.valid()) {
       // handle error or exit
   }

   // ...
} // destructors clean up as usual

关于C++中怎么使用RAII防止资源泄露问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. 怎么在Golang中防止 goroutine 泄露
  2. Android中怎么利用Handler防止内存泄露

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++

上一篇:C++中如何使用联合体节约内存

下一篇:C++中避免使用do语句的原因是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》