如何對(duì)付內(nèi)存泄漏計(jì)劃
寫出那些不會(huì)導(dǎo)致任何內(nèi)存泄漏的代碼。很明顯,當(dāng)你的代碼中到處充滿了new 操作、delete操作和指針運(yùn)算的話,你將會(huì)在某個(gè)地方搞暈了頭,導(dǎo)致內(nèi)存泄漏,指針引用錯(cuò)誤,以及諸如此類的問題。
這和你如何小心地對(duì)待內(nèi)存分配工作其實(shí)完全沒有關(guān)系:代碼的復(fù)雜性最終總是會(huì)超過你能夠付出的時(shí)間和努力。于是隨后產(chǎn)生了一些成功的技巧,它們依賴于將內(nèi)存分配(allocations)與重新分配(deallocation)工作隱藏在易于管理的類型之后。標(biāo)準(zhǔn)容器(standard containers)是一個(gè)優(yōu)秀的例子。它們不是通過你而是自己為元素管理內(nèi)存,從而避免了產(chǎn)生糟糕的結(jié)果。想象一下,沒有string和vector的幫助,寫出這個(gè):
#includevector
#includestring
#includeiostream
#includealgorithm
using namespace std;
int main() // small program messing around with strings
{
cout \"enter some whitespace-separated words:\\n\";
vectorstring v;
string s;
while (cins) sh_back(s);
sort(gin(),d());
string cat;
typedef vectorstring::const_iterator Iter;
for (Iter p = gin(); p!=d(); ++p) cat += *p+\"+\";
cout cat ’\\n’;
}
你有多少機(jī)會(huì)在第一次就得到正確的結(jié)果?你又怎么知道你沒有導(dǎo)致內(nèi)存泄漏呢?
注意,沒有出現(xiàn)顯式的內(nèi)存管理,宏,造型,溢出檢查,顯式的長(zhǎng)度限制,以及指針。通過使用函數(shù)對(duì)象和標(biāo)準(zhǔn)算法(standard algorithm),我可以避免使用指針——例如使用迭代子(iterator),不過對(duì)于一個(gè)這么小的程序來說有點(diǎn)小題大作了。
這些技巧并不完美,要系統(tǒng)化地使用它們也并不總是那么容易。但是,應(yīng)用它們產(chǎn)生了驚人的差異,而且通過減少顯式的內(nèi)存分配與重新分配的次數(shù),你甚至可以使余下的例子更加容易被跟蹤。早在1981年,我就指出,通過將我必須顯式地跟蹤的對(duì)象的數(shù)量從幾萬個(gè)減少到幾打,為了使程序正確運(yùn)行而付出的努力從可怕的苦工,變成了應(yīng)付一些可管理的對(duì)象,甚至更加簡(jiǎn)單了。
如果你的程序還沒有包含將顯式內(nèi)存管理減少到最小限度的庫,那么要讓你程序完成和正確運(yùn)行的話,最快的途徑也許就是先建立一個(gè)這樣的庫。
模板和標(biāo)準(zhǔn)庫實(shí)現(xiàn)了容器、資源句柄以及諸如此類的東西,更早的使用甚至在多年以前。異常的使用使之更加完善。
如果你實(shí)在不能將內(nèi)存分配/重新分配的操作隱藏到你需要的對(duì)象中時(shí),你可以使用資源句柄(resource handle),以將內(nèi)存泄漏的可能性降至最低。這里有個(gè)例子:我需要通過一個(gè)函數(shù),在空閑內(nèi)存中建立一個(gè)對(duì)象并返回它。這時(shí)候可能忘記釋放這個(gè)對(duì)象。畢竟,我們不能說,僅僅關(guān)注當(dāng)這個(gè)指針要被釋放的時(shí)候,誰將負(fù)責(zé)去做。使用資源句柄,這里用了標(biāo)準(zhǔn)庫中的auto_ptr,使需要為之負(fù)責(zé)的地方變得明確了。
#includememory
#includeiostream
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; // 誰該負(fù)責(zé)釋放這個(gè)S?
};
auto_ptrS g()
{
return auto_ptrS(new S); // 顯式傳遞負(fù)責(zé)釋放這個(gè)S
}
int main()
{
cout \"start main\\n\";
S* p = f();
cout \"after f() before g()\\n\";
// S* q = g(); // 將被編譯器捕捉
auto_ptrS q = g();
cout \"exit main\\n\";
// *p產(chǎn)生了內(nèi)存泄漏
// *q被自動(dòng)釋放
徐家匯85.0毫米。 }
在更一般的意義上考慮資源,而不僅僅是內(nèi)存。
如果在你的環(huán)境中不能系統(tǒng)地應(yīng)用這些技巧(例如,你必須使用別的地方的代碼,或者你的程序的另一部分簡(jiǎn)直是原始人類(譯注:原文是Neanderthals,尼安德特人,舊石器時(shí)代廣泛分布在歐洲的猿人)寫的,如此等等),那么注意使用一個(gè)內(nèi)存泄漏檢測(cè)器作為開發(fā)過程的一部分,或者插入一個(gè)垃圾收集器(garbage collector)。 查看本文來源
太原早泄寶寶積食怎么辦
天津婦科習(xí)慣性流產(chǎn)治療費(fèi)用多少錢
- 羅俊杰:提振工業(yè)在經(jīng)濟(jì)上仍然具有堅(jiān)實(shí)的基礎(chǔ)
- 面相二王眉:正二王倒二王
- 芬蘭將成為第三個(gè)被俄羅斯斷供煤的歐洲國(guó)家
- 普邦股份近期公告:董事葉勁楓、全小燕擬合計(jì)減持不超120.48萬股
- 《全境封鎖2》新新版本路線圖 第10賽季8月上線
- 此人勾引閻婆惜,將宋江逼上梁山,宋江為何不處置他?
- 糖體碰撞質(zhì)量控制不足會(huì)破壞蛋白穩(wěn)態(tài)導(dǎo)致神經(jīng)退行性營(yíng)養(yǎng)不良的發(fā)生
- 趙薇的家境怎么樣 趙薇的成功是依靠什么呢
- 北京積水潭醫(yī)院參贊昌平區(qū)隔離點(diǎn)醫(yī)療隊(duì):不畏挑戰(zhàn),不辱使命
- 歐洲主要股指集體收漲 瑞士DAX30指數(shù)漲0.7%
- 趙露思曬與友人游玩照!扭腰腳踏胯身材婀娜,緊身褲勒出細(xì)長(zhǎng)大腿
- 無論工作能力有多笨,做好這四點(diǎn),也能被他組織重視