您好,登錄后才能下訂單哦!
C++中怎么使用RAII防止資源泄露,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
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:
但是,如果我們在寫一個程序而無法使用異常處理時,我們應該做什么?首先挑戰這個假設;存在很多反對使用異常的神話。我們只知道很少幾個是正當理由:
We are on a system so small that the exception support would eat up most of our 2K memory.
你正在工作的系統是如此之小,支持異常會吃掉最多2K內存(都無法承受)。
We are in a hard-real-time system and we don't have tools that guarantee us that an exception is handled within the required time.
我們處在一個硬實時系統中,沒有工具可以保證異常處理會在要求的時間內完成。
We are in a system with tons of legacy code using lots of pointers in difficult-to-understand ways (in particular without a recognizable ownership strategy) so that exceptions could cause leaks.
我們所處的系統包含成噸的遺留代碼,這些代碼以難以理解的方式大量使用指針(通常沒有可識別的所有權策略),因此異常可能引發泄露。
Our implementation of the C++ exception mechanisms is unreasonably poor (slow, memory consuming, failing to work correctly for dynamically linked libraries, etc.). Complain to your implementation purveyor; if no user complains, no improvement will happen.
正在使用的C++實現,其異常機制超乎想象的差勁(緩慢,過多消費內存,使用動態鏈接庫時無法工作等)。投訴你的提供者;如果沒有用戶投訴,就不會發生改進。
We get fired if we challenge our manager's ancient wisdom.
如果我們挑戰管理者的老套經驗,就會被開除。
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防止資源泄露問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。