日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

内存的静态分配和动态分配的区别【转】 静态分配内存与动态分配内存的区别

發(fā)布時(shí)間:2025/4/5 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存的静态分配和动态分配的区别【转】 静态分配内存与动态分配内存的区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

內(nèi)存的靜態(tài)分配和動(dòng)態(tài)分配的區(qū)別【轉(zhuǎn)】

來源:?<http://blog.csdn.net/liuchao1986105/article/details/6724392>

內(nèi)存的靜態(tài)分配和動(dòng)態(tài)分配的區(qū)別主要是兩個(gè)

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

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

? ??對(duì)于一個(gè)進(jìn)程的內(nèi)存空間而言,可以在邏輯上分成3個(gè)部份:代碼區(qū)靜態(tài)數(shù)據(jù)區(qū)動(dòng)態(tài)數(shù)據(jù)區(qū)

? ??動(dòng)態(tài)數(shù)據(jù)區(qū)一般就是“堆棧”。“棧(stack)”和“堆(heap)”是兩種不同的動(dòng)態(tài)數(shù)據(jù)區(qū),棧是一種線性結(jié)構(gòu),堆是一種鏈?zhǔn)浇Y(jié)構(gòu)。進(jìn)程的每個(gè)線程都有私有的“棧”,所以每個(gè)線程雖然代碼一樣,但本地變量的數(shù)據(jù)都是互不干擾。一個(gè)堆棧可以通過“基地址”和“棧頂”地址來描述。全局變量和靜態(tài)變量分配在靜態(tài)數(shù)據(jù)區(qū),本地變量分配在動(dòng)態(tài)數(shù)據(jù)區(qū),即堆棧中。程序通過堆棧的基地址和偏移量來訪問本地變量。

?

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

?

? ??所謂動(dòng)態(tài)內(nèi)存分配就是指在程序執(zhí)行的過程中動(dòng)態(tài)地分配或者回收存儲(chǔ)空間的分配內(nèi)存的方法。動(dòng)態(tài)內(nèi)存分配不象數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預(yù)先分配存儲(chǔ)空間,而是由系統(tǒng)根據(jù)程序的需要即時(shí)分配,且分配的大小就是程序要求的大小。
? ??例如我們定義一個(gè)float型數(shù)組:

? ??? ??float score[100];   

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

? ??靜態(tài)內(nèi)存是在程序一開始運(yùn)行就會(huì)分配內(nèi)存,直到程序結(jié)束了,內(nèi)存才被釋放。
? ??動(dòng)態(tài)內(nèi)存是在程序調(diào)用在程序中定義的函數(shù)時(shí)才被分配,函數(shù)調(diào)用結(jié)束了,動(dòng)態(tài)內(nèi)存就釋放。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

static?int a;??????/*?這是定義了一個(gè)靜態(tài)的變量?*/

int???? a;??????/*?這是定義了一個(gè)動(dòng)態(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?)?);

}

?

? ??運(yùn)行
? ??輸入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)存會(huì)隨malloc越來越少,直到系統(tǒng)崩潰。還是來看看“棧內(nèi)存”和“堆內(nèi)存”的差別吧。

? ? 棧內(nèi)存分配

1

2

3

4

5

6

????char*

????AllocStrFromStack()

????{

????????char?pstr[100];

????????return?pstr;

????}

???
??? 堆內(nèi)存分配

1

2

3

4

5

6

7

8

char*?AllocStrFromHeap(?int?len?)

{

????char?*pstr;

?

????if?(?len?<=?0?)

????????return(NULL);

????return(?(?char?*?)?malloc(?len?)?);

}

? ??

? ??對(duì)于第一個(gè)函數(shù),那塊pstr的內(nèi)存在函數(shù)返回時(shí)就被系統(tǒng)釋放了。于是所返回的char*什么也沒有。而對(duì)于第二個(gè)函數(shù),是從堆上分配內(nèi)存,所以哪怕是程序退出時(shí),也不釋放,所以第二個(gè)函數(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)時(shí)千萬要小心。

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

? ??我保證,做過許多C/C++的工程的程序員,都會(huì)對(duì)malloc或是new有些感冒。當(dāng)你什么時(shí)候在使用malloc和new時(shí),有一種輕度的緊張和惶恐的感覺時(shí),你就具備了這方面的修養(yǎng)了。

對(duì)于malloc和free的操作有以下規(guī)則:

1) 配對(duì)使用,有一個(gè)malloc,就應(yīng)該有一個(gè)free。(C++中對(duì)應(yīng)為new和delete)

2) 盡量在同一層上使用,不要像上面那種,malloc在函數(shù)中,而free在函數(shù)外。最好在同一調(diào)用層上使用這兩個(gè)函數(shù)。

3) malloc分配的內(nèi)存一定要初始化。free后的指針一定要設(shè)置為NULL。? ??


注:雖然現(xiàn)在的操作系統(tǒng)(如:UNIX和Win2k/NT)都有進(jìn)程內(nèi)存跟蹤機(jī)制,也就是如果你有沒有釋放的內(nèi)存,操作系統(tǒng)會(huì)幫你釋放。但操作系統(tǒng)依然不會(huì)釋放你程序中所有產(chǎn)生了Memory Leak的內(nèi)存,所以,最好還是你自己來做這個(gè)工作。(有的時(shí)候不知不覺就出現(xiàn)Memory Leak了,而且在幾百萬行的代碼中找無異于海底撈針,Rational有一個(gè)工具叫Purify,可能很好的幫你檢查程序中的Memory Leak)

?

? ??第一個(gè)例子也講得不清楚。所謂系統(tǒng)釋放,應(yīng)該是指系統(tǒng)在自己的表里把這段內(nèi)存標(biāo)記為可以使用,以后可以被別的程序使用,所以第一個(gè)例子會(huì)造成程序能訪問到已經(jīng)釋放的內(nèi)存空間,是越界,會(huì)造成不可預(yù)測的情況。
? ??系統(tǒng)一般不會(huì)自動(dòng)去清除釋放空間內(nèi)的數(shù)據(jù),而是由以后的程序來覆蓋。所以很多程序開頭都會(huì)做MEMSET(...) ,就是為了防止這種垃圾數(shù)據(jù)的情況。
? ??如果在程序運(yùn)行中要改變內(nèi)存塊的大小,可以用RALLOC()函數(shù),它能在原來地址上重新分配一塊空間,不過是用的時(shí)候要小心,也是比較容易出問題

?

?

?

標(biāo)簽:?C,?C++,?操作系統(tǒng)

好文要頂?關(guān)注我?收藏該文??

copperface
關(guān)注 - 3
粉絲 - 11

+加關(guān)注

0

0

??上一篇:c++面試題【轉(zhuǎn)】
??下一篇:高壓縮文件是如何實(shí)現(xiàn)的

?

總結(jié)

以上是生活随笔為你收集整理的内存的静态分配和动态分配的区别【转】 静态分配内存与动态分配内存的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。