?? xielou.txt
字號:
Q: 我應該怎樣處理內存泄漏?
A: 很簡單,只要寫“不漏”的代碼就完事了啊。顯然,如果你的代碼到處是new、delete、指針運算,那你想讓它“不漏”都難。不管你有多么小心謹慎,君為人,非神也,錯誤在所難免。最終你會被自己越來越復雜的代碼逼瘋的——你將投身于與內存泄漏的奮斗之中,對bug們不離不棄,直至山峰沒有棱角,地球不再轉動。而能讓你避免這樣困境的技巧也不復雜:你只要倚重隱含在幕后的分配機制——構造和析構,讓C++的強大的類系統來助你一臂之力就OK了。標準庫中的那些容器就是很好的實例。它們讓你不必化費大量的時間精力也能輕松愜意地管理內存。我們來看看下面的示例代碼——設想一下,如果沒有了string和vector,世界將會怎樣?如果不用它們,你能第一次就寫出毫無內存錯誤的同樣功能代碼嗎?
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
int main() // small program messing around with strings
{
cout << "enter some whitespace-separated words:\n";
vector<string> v;
string s;
while (cin>>s) v.push_back(s);
sort(v.begin(),v.end());
string cat;
typedef vector<string>::const_iterator Iter;
for (Iter p = v.begin(); p!=v.end(); ++p) cat += *p+"+";
cout << cat << '\n';
}
請注意這里沒有顯式的內存管理代碼。沒有宏,沒有類型轉換,沒有溢出檢測,沒有強制的大小限制,也沒有指針。如果使用function object和標準算法[譯注:指標準庫中提供的泛型算法],我連Iterator也可以不用。不過這畢竟只是一個小程序,殺雞焉用牛刀?
當然,這些方法也并非無懈可擊,而且說起來容易做起來難,要系統地使用它們也并不總是很簡單。不過,無論如何,它們的廣泛適用性令人驚訝,而且通過移去大量的顯式內存分配/釋放代碼,它們確實增強了代碼的可讀性和可管理性。早在 1981年,我就指出通過大幅度減少需要顯式加以管理的對象數量,使用C++“將事情做對”將不再是一件極其費神的艱巨任務。
如果你的應用領域沒有能在內存管理方面助你一臂之力的類庫,那么如果你還想讓你的軟件開發變得既快捷又能輕松得到正確結果,最好是先建立這樣一個庫。
如果你無法讓內存分配和釋放成為對象的“自然行為”,那么至少你可以通過使用資源句柄來盡量避免內存泄漏。這里是一個示例:假設你需要從函數返回一個對象,這個對象是在自由內存堆上分配的;你可能會忘記釋放那個對象——畢竟我們無法通過檢查指針來確定其指向的對象是否需要被釋放,我們也無法得知誰應該負責釋放它。那么,就用資源句柄吧。比如,標準庫中的auto_ptr就可以幫助澄清:“釋放對象”責任究竟在誰。我們來看:
#include<memory>
#include<iostream>
using namespace std;
struct S {
S() { cout << "make an S\n"; }
~S() { cout << "destroy an S\n"; }
S(const S&) { cout << "copy initialize an S\n"; }
S& operator=(const S&) { cout << "copy assign an S\n"; }
};
S* f()
{
return new S; // who is responsible for deleting this S?
};
auto_ptr<S> g()
{
return auto_ptr< S >(new S); // explicitly transfer responsibility for deleting this S
}
int main()
{
cout << "start main\n";
S* p = f();
cout << "after f() before g()\n";
// S* q = g(); // caught by compiler
auto_ptr< S > q = g();
cout << "exit main\n";
// leaks *p
// implicitly deletes *q
}
這里只是內存資源管理的例子;至于其它類型的資源管理,可以如法炮制。
如果在你的開發環境中無法系統地使用這種方法(比方說,你使用了第三方提供的古董代碼,或者遠古“穴居人”參與了你的項目開發),那么你在開發過程中可千萬要記住使用內存防漏檢測程序,或者干脆使用垃圾收集器(Garbage Collector)。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -