一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

內(nèi)存的靜態(tài)分配和動態(tài)分配的區(qū)別

 thchen0103 2017-03-05
   內(nèi)存的靜態(tài)分配和動態(tài)分配的區(qū)別主要是兩個:

      一是時間不同。靜態(tài)分配發(fā)生在程序編譯和連接的時候。動態(tài)分配則發(fā)生在程序調(diào)入和執(zhí)行的時候。

      二是空間不同。堆都是動態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由函數(shù)malloc進(jìn)行分配。不過棧的動態(tài)分配和堆不同,他的動態(tài)分配是由編譯器進(jìn)行釋放,無需我們手工實現(xiàn)。    

對于一個進(jìn)程的內(nèi)存空間而言,可以在邏輯上分成3個部份:代碼區(qū),靜態(tài)數(shù)據(jù)區(qū)和動態(tài)數(shù)據(jù)區(qū)。動態(tài)數(shù)據(jù)區(qū)一般就是“堆?!??!皸?stack)”和“堆(heap)”是兩種不同的動態(tài)數(shù)據(jù)區(qū),棧是一種線性結(jié)構(gòu),堆是一種鏈?zhǔn)浇Y(jié)構(gòu)。進(jìn)程的每個線程都有私有的“?!?,所以每個線程雖然代碼一樣,但本地變量的數(shù)據(jù)都是互不干擾。一個堆??梢酝ㄟ^“基地址”和“棧頂”地址來描述。全局變量和靜態(tài)變量分配在靜態(tài)數(shù)據(jù)區(qū),本地變量分配在動態(tài)數(shù)據(jù)區(qū),即堆棧中。程序通過堆棧的基地址和偏移量來訪問本地變量。

 

一般,用static修飾的變量,全局變量位于靜態(tài)數(shù)據(jù)區(qū)。函數(shù)調(diào)用過程中的參數(shù),返回地址,EBP和局部變量都采用棧的方式存放。

 

 

所謂動態(tài)內(nèi)存分配就是指在程序執(zhí)行的過程中動態(tài)地分配或者回收存儲空間的分配內(nèi)存的方法。動態(tài)內(nèi)存分配不象數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預(yù)先分配存儲空間,而是由系統(tǒng)根據(jù)程序的需要即時分配,且分配的大小就是程序要求的大小。
例如我們定義一個float型數(shù)組:float score[100];   
但是,在使用數(shù)組的時候,總有一個問題困擾著我們:數(shù)組應(yīng)該有多大?在很多的情況下,你并不能確定要使用多大的數(shù)組,比如上例,你可能并不知道我們要定義的這個數(shù)組到底有多大,那么你就要把數(shù)組定義得足夠大。這樣,你的程序在運行時就申請了固定大小的你認(rèn)為足夠大的內(nèi)存空間。即使你知道你想利用的空間大小,但是如果因為某種特殊原因空間利用的大小有增加或者減少,你又必須重新去修改程序,擴(kuò)大數(shù)組的存儲范圍。這種分配固定大小的內(nèi)存分配方法稱之為靜態(tài)內(nèi)存分配。但是這種內(nèi)存分配的方法存在比較嚴(yán)重的缺陷,特別是處理某些問題時:在大多數(shù)情況下會浪費大量的內(nèi)存空間,在少數(shù)情況下,當(dāng)你定義的數(shù)組不夠大時,可能引起下標(biāo)越界錯誤,甚至導(dǎo)致嚴(yán)重后果。
我們用動態(tài)內(nèi)存分配就可以解決上面的問題. 所謂動態(tài)內(nèi)存分配就是指在程序執(zhí)行的過程中動態(tài)地分配或者回收存儲空間的分配內(nèi)存的方法。動態(tài)內(nèi)存分配不象數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預(yù)先分配存儲空間,而是由系統(tǒng)根據(jù)程序的需要即時分配,且分配的大小就是程序要求的大小。從以上動、靜態(tài)內(nèi)存分配比較可以知道動態(tài)內(nèi)存分配相對于景泰內(nèi)存分配的特點:
   1、不需要預(yù)先分配存儲空間;
   2、分配的空間可以根據(jù)程序的需要擴(kuò)大或縮小。
要實現(xiàn)根據(jù)程序的需要動態(tài)分配存儲空間,就必須用到malloc函數(shù).
malloc函數(shù)的原型為:void *malloc (unsigned int size) 其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個長度為size的連續(xù)空間。其參數(shù)是一個無符號整形數(shù),返回值是一個指向所分配的連續(xù)存儲域的起始地址的指針。還有一點必須注意的是,當(dāng)函數(shù)未能成功分配存儲空間(如內(nèi)存不足)就會返回一個NULL指針。所以在調(diào)用該函數(shù)時應(yīng)該檢測返回值是否為NULL并執(zhí)行相應(yīng)的操作。
靜態(tài)內(nèi)存是在程序一開始運行就會分配內(nèi)存,直到程序結(jié)束了,內(nèi)存才被釋放。
動態(tài)內(nèi)存是在程序調(diào)用在程序中定義的函數(shù)時才被分配,函數(shù)調(diào)用結(jié)束了,動態(tài)內(nèi)存就釋放。
static int a;這是定義了一個靜態(tài)的變量
int a;這是定義了一個動態(tài)的變量;
靜態(tài)內(nèi)存可以用于求階層。
例如:
jiechen(int i)
{static int a=1;
for(;a<=i,a++)
return a*i;
}
#include"stdio.h"
main()
{int a,i;
printf("enter number:")
scanf("%d",&a);
for(i=1;i<=a;i++)
printf("i!=%d\n",jiechen(i));

}
運行
輸入3
結(jié)果為1!=1
      2!=2
      3!=3
由malloc系統(tǒng)函數(shù)分配的內(nèi)存就是從堆上分配內(nèi)存。從堆上分配的內(nèi)存一定要自己釋放。用free釋放,不然就是術(shù)語——“內(nèi)存泄露”(或是“內(nèi)存漏洞”)—— Memory Leak。于是,系統(tǒng)的可分配內(nèi)存會隨malloc越來越少,直到系統(tǒng)崩潰。還是來看看“棧內(nèi)存”和“堆內(nèi)存”的差別吧。

    棧內(nèi)存分配
    —————
    char*
    AllocStrFromStack()
    {
        char pstr[100];
        return pstr;
    }
  
    堆內(nèi)存分配
    —————
    char*
    AllocStrFromHeap(int len)
    {
        char *pstr;
       
        if ( len <= 0 ) return NULL;
        return ( char* ) malloc( len );
    }

對于第一個函數(shù),那塊pstr的內(nèi)存在函數(shù)返回時就被系統(tǒng)釋放了。于是所返回的char*什么也沒有。而對于第二個函數(shù),是從堆上分配內(nèi)存,所以哪怕是程序退出時,也不釋放,所以第二個函數(shù)的返回的內(nèi)存沒有問題,可以被使用。但一定要調(diào)用free釋放,不然就是Memory Leak!

在堆上分配內(nèi)存很容易造成內(nèi)存泄漏,這是C/C++的最大的“克星”,如果你的程序要穩(wěn)定,那么就不要出現(xiàn)Memory Leak。所以,我還是要在這里千叮嚀萬囑付,在使用malloc系統(tǒng)函數(shù)(包括calloc,realloc)時千萬要小心。

記得有一個UNIX上的服務(wù)應(yīng)用程序,大約有幾百的C文件編譯而成,運行測試良好,等使用時,每隔三個月系統(tǒng)就是down一次,搞得許多人焦頭爛額,查不出問題所在。只好,每隔兩個月人工手動重啟系統(tǒng)一次。出現(xiàn)這種問題就是Memery Leak在做怪了,在C/C++中這種問題總是會發(fā)生,所以你一定要小心。一個Rational的檢測工作——Purify,可以幫你測試你的程序有沒有內(nèi)存泄漏。

我保證,做過許多C/C++的工程的程序員,都會對malloc或是new有些感冒。當(dāng)你什么時候在使用malloc和new時,有一種輕度的緊張和惶恐的感覺時,你就具備了這方面的修養(yǎng)了。
對于malloc和free的操作有以下規(guī)則:

1) 配對使用,有一個malloc,就應(yīng)該有一個free。(C++中對應(yīng)為new和delete)
2) 盡量在同一層上使用,不要像上面那種,malloc在函數(shù)中,而free在函數(shù)外。最好在同一調(diào)用層上使用這兩個函數(shù)。
3) malloc分配的內(nèi)存一定要初始化。free后的指針一定要設(shè)置為NULL。   

注:雖然現(xiàn)在的操作系統(tǒng)(如:UNIX和Win2k/NT)都有進(jìn)程內(nèi)存跟蹤機(jī)制,也就是如果你有沒有釋放的內(nèi)存,操作系統(tǒng)會幫你釋放。但操作系統(tǒng)依然不會釋放你程序中所有產(chǎn)生了Memory Leak的內(nèi)存,所以,最好還是你自己來做這個工作。(有的時候不知不覺就出現(xiàn)Memory Leak了,而且在幾百萬行的代碼中找無異于海底撈針,Rational有一個工具叫Purify,可能很好的幫你檢查程序中的Memory Leak)
第一個例子也講得不清楚。所謂系統(tǒng)釋放,應(yīng)該是指系統(tǒng)在自己的表里把這段內(nèi)存標(biāo)記為可以使用,以后可以被別的程序使用,所以第一個例子會造成程序能訪問到已經(jīng)釋放的內(nèi)存空間,是越界,會造成不可預(yù)測的情況。
系統(tǒng)一般不會自動去清除釋放空間內(nèi)的數(shù)據(jù),而是由以后的程序來覆蓋。所以很多程序開頭都會做MEMSET(...),就是為了防止這種垃圾數(shù)據(jù)的情況。
如果在程序運行中要改變內(nèi)存塊的大小,可以用RALLOC()函數(shù),它能在原來地址上重新分配一塊空間,不過是用的時候要小心,也是比較容易出問題


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲视频偷拍福利来袭| 久久精品国产一区久久久| 欧美日韩亚洲精品内裤| 久久热中文字幕在线视频| 色婷婷中文字幕在线视频| 高潮日韩福利在线观看| 在线观看免费视频你懂的| 永久福利盒子日韩日韩| 久热青青草视频在线观看| 91人妻人人揉人人澡人| 黄色片国产一区二区三区| 亚洲一区二区三区精选| 成人国产激情福利久久| 色哟哟在线免费一区二区三区| 亚洲欧美日韩在线看片| 亚洲国产一区精品一区二区三区色| 日韩一区二区三区四区乱码视频 | 好吊色欧美一区二区三区顽频| 成人日韩在线播放视频| 国产午夜福利不卡片在线观看| 国产午夜免费在线视频| 国产av天堂一区二区三区粉嫩| 好吊妞视频这里有精品| 激情图日韩精品中文字幕| 国产精品久久精品国产| 久草视频在线视频在线观看| 黄色美女日本的美女日人| 视频一区中文字幕日韩| 国内欲色一区二区三区| 国产中文字幕一二三区| 久久精品少妇内射毛片| 国产一区二区三区香蕉av| 亚洲综合伊人五月天中文 | 高清不卡一卡二卡区在线| 欧美日韩国产一级91| 国产午夜精品美女露脸视频| 欧美一区二区三区喷汁尤物| 国产亚洲神马午夜福利| 欧美大胆女人的大胆人体| 中文字幕亚洲在线一区| 出差被公高潮久久中文字幕|