內(nèi)存溢出與內(nèi)存泄漏的解析

責(zé)任編輯:editor006

作者:大明同學(xué)

2015-03-30 14:44:34

摘自:博客園

我們在實際編程中經(jīng)常會說到內(nèi)存溢出和內(nèi)存泄漏,特別對于C C++程序來說(以下代碼示例均為C C++),因為這時我們會跟內(nèi)存直接打交道。根據(jù)內(nèi)存泄漏的發(fā)生頻率,一般內(nèi)存泄漏可分為以下4種:常發(fā)性內(nèi)存泄漏;

我們在實際編程中經(jīng)常會說到內(nèi)存溢出和內(nèi)存泄漏,特別對于C/C++程序來說(以下代碼示例均為C/C++),因為這時我們會跟內(nèi)存直接打交道。然而很多時候我們并不能完全搞明白這兩個概念,有時甚至?xí)⒍哳嵉够煜?/p>

其實從命名上也能明白內(nèi)存溢出和內(nèi)存泄漏的大概,舉個可能并不恰當(dāng)?shù)睦?。好比是往水缸里打水,本來這個缸只能裝下5桶水,第5桶裝完你還硬要裝第6桶,缸里的水自然就溢出來了,此為“內(nèi)存溢出”;缸里打滿水后并沒有人用,第二天發(fā)現(xiàn)缸里的水少了一半,第三天一滴不剩了,原來是缸底打了個洞忘補了(為什么要在缸底打洞呢?不為什么,好玩,任性)。這就好比是申請了一塊內(nèi)存忘記釋放了,造成了“內(nèi)存泄漏”。下面將簡要解析一下這兩個概念。

首先說說內(nèi)存溢出,內(nèi)存溢出簡單的說,即指要求分配的內(nèi)存超出了系統(tǒng)所能提供的,比如你申請了一個10字節(jié)的內(nèi)存空間,你硬要往里塞11字節(jié)大小的數(shù)據(jù),自然就滿了,溢出了嘛(如代碼示例1)。其實數(shù)組越界也是一種內(nèi)存溢出,比如寫數(shù)據(jù)時超出了數(shù)組范圍(越界讀數(shù)組數(shù)據(jù)并不算內(nèi)存溢出)。數(shù)組填充越界以后,再往里塞的話,就會擠占棧內(nèi)存(一般數(shù)組聲明為局部變量,局部變量在棧區(qū)自動分配內(nèi)存)。越界的部分被當(dāng)作局部變量占用棧內(nèi)存,因為棧是從RAM的底部往上長(存數(shù)據(jù))的,而程序運行的其他數(shù)據(jù)是從頂部往下的,所以當(dāng)棧越存越多,越積越高的時候,棧就會和程序運行時的數(shù)據(jù)碰頭,二者占滿整個RAM內(nèi)存,此時棧再繼續(xù)消耗,棧再向上長,直接覆蓋掉程序運行時所需的變量,程序就要跑飛了。這么看來內(nèi)存溢出也是很可怕的。

void arr_test() {   int arr[10];   arr[10] = 10; }

接著說說內(nèi)存泄漏,一般所說的內(nèi)存泄漏是指堆內(nèi)存的泄漏(Heap leak),在對堆上動態(tài)申請內(nèi)存,使用后未及時釋放,即會出現(xiàn)內(nèi)存泄漏。順帶說一下,如果釋放了指針?biāo)竷?nèi)存,但是未立即將指針置為NULL,就會造成野指針(如代碼示例2)。一次內(nèi)存泄漏可能不會被察覺,可能也不會有什么危害,但是內(nèi)存泄漏的累積會造成內(nèi)存用竭,那后果就嚴(yán)重了。比如內(nèi)存泄漏出現(xiàn)在循環(huán)體中。當(dāng)然還另有一些其他形式的內(nèi)存泄漏,如由于系統(tǒng)資源的泄漏(Resource leak )造成的內(nèi)存泄漏等等。根據(jù)內(nèi)存泄漏的發(fā)生頻率,一般內(nèi)存泄漏可分為以下4種:
常發(fā)性內(nèi)存泄漏;
偶發(fā)性內(nèi)存泄漏;
一次性內(nèi)存泄漏;
隱式內(nèi)存泄漏。

1 void heap-leap_test 2 { 3   char *p = (char *)malloc(sizeof(char)); 4   //exe task 5   free(p);//若不釋放指針p所指內(nèi)存空間,則會造成內(nèi)存泄漏。 6  p = NULL;//若不置指針p為NULL,則p就會成為野指針。 7 }

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號-6京公網(wǎng)安備 11010502049343號