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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

内存的管理方式

發(fā)布時間:2023/11/30 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 内存的管理方式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、內(nèi)存的區(qū)域

??? 對于內(nèi)存的區(qū)域劃分上,不同的區(qū)域劃分上都各有不同。

劃分1:

代碼區(qū)、堆、棧、 全局區(qū)(靜態(tài)存儲區(qū))、 文字常量區(qū)、

劃分2:

代碼段、堆、棧、? data段、BSS段、文字常量區(qū)

全局區(qū):

??? 又成為靜態(tài)存存儲區(qū)。保存的是全局變量和靜態(tài)變量(帶有static 關(guān)鍵字)。全局區(qū)分為兩個區(qū)域:一個區(qū)域保存的是經(jīng)過初始化,且初始化的值不為零的全部變量和靜態(tài)變量;一個區(qū)域保存的是沒有經(jīng)過初始化或者初始化的值為零的。程序結(jié)束由 OS 進(jìn)行釋放

常量區(qū):

??? 將一些不可以被更改的只讀的常量進(jìn)行保存的區(qū)域。比如文字字符串等。程序結(jié)束之后由系統(tǒng)釋放。

代碼區(qū):

??? 保存的是二進(jìn)制代碼的區(qū)域。

堆:

??? 由程序猿手動 malloc/free進(jìn)行開辟的空間,一般也是由程序猿調(diào)用 free/delete 進(jìn)行釋放,即使沒有進(jìn)行釋放,也可以由 OS 進(jìn)行釋放。

棧:

??? 程序運行的時候由編系統(tǒng)進(jìn)行分配,存在函數(shù)的的局部變量等。程序結(jié)束由系統(tǒng)自動釋放。

DATA段:

??? 有經(jīng)過初始化的全局變量和靜態(tài)變量存儲的區(qū)域,當(dāng)然初始值不能為零

BSS段:

??? 保存的是沒有經(jīng)過初始化的全局變量和靜態(tài)變量存儲的區(qū)域,或者經(jīng)過初始化但是初始值為零的也保存在這個區(qū)域。

注意:很顯然,DATA 段和 BSS 段的也行,其實就是全局區(qū)(靜態(tài)存儲器)內(nèi)部之一,DATA 段和 BSS 段只不過是全局區(qū)更加精細(xì)的劃分。

解釋:

??? 借助前人總結(jié)的知識:

int a = 0; 全局初始化區(qū) char *p1; 全局未初始化區(qū) main() { int b; //char s[] = "abc"; //char *p2; //char *p3 = "123456"; //"123456/0"在常量區(qū),p3在棧上。 static int c =0//全局(靜態(tài))初始化區(qū) p1 = (char *)malloc(10); p2 = (char *)malloc(20); //分配得來得10和20字節(jié)的區(qū)域就在堆區(qū)。 strcpy(p1, "123456"); // 123456 放在常量區(qū),編譯器可能會將它與p3所指向的"123456" //優(yōu)化成一個地方。 }

?

2、內(nèi)存的三種來源:棧、堆、全局區(qū)

棧:

??? (1)運行時候由編譯器自動分配自動回收,這一切都是自動的,程序猿不用管理

??? (2)反復(fù)使用:每一個進(jìn)程,操作系統(tǒng)都會為這個進(jìn)程分配棧,這個進(jìn)程不論是怎么出入棧,都是在這個棧,反復(fù)使用。

??? (3)臟內(nèi)存:棧內(nèi)存由于反復(fù)的使用,程序使用完畢之后不會去做清理的工作,所以重新使用棧的時候,值就是臟的。

??? (4)臨時性:局部變量的出棧入棧,每次都是不一樣,所以都是臨時性的,所以,絕對不要返回棧變量的指針,因為棧地址都是臨時的,

??? (5)棧溢出:因為棧的大小是操作系統(tǒng)設(shè)定的,當(dāng)出現(xiàn)無線遞歸或者出現(xiàn)巨大的局部變量。

堆:

??? (1)大塊內(nèi)存:棧的空間非常有限,所以當(dāng)需要需要大塊內(nèi)存的時候,就在堆進(jìn)行申請,

??? (2)手動申請、釋放: 使用 malloc/new 申請,free/delete 進(jìn)行釋放。

??? (3)臟內(nèi)存 : 堆內(nèi)存也是被反復(fù)使用的

malloc 實際應(yīng)用:

??? 操作系統(tǒng)會對空閑的內(nèi)存塊進(jìn)行組織管理,而這種組織管理的方式是以鏈表的形式。當(dāng)程序猿調(diào)用 malloc 的時候就從空閑的鏈表找出一塊大小滿足申請要求的空間(可以比用戶申請的大),然后將這個內(nèi)存空間一分為二:一部分是用戶申請空間的大小,另外的部分是維護(hù)鏈表這個節(jié)點的基本信息(比如地址、塊內(nèi)存的大小)。所以當(dāng) malloc 的時候,不論申請的空間是多大,都必須申請一塊用于維護(hù)鏈表的空間。

#include <stdio.h> #include<stdlib.h> int main(void) {int i,j;FILE * fp = fopen("qxj511.txt", "w");for ( i = 0; i < 2048; i++){int *p1 = (int *)malloc(i);int *p2 = (int *)malloc(i);fprintf(fp, "i =%d : p1 = %d, p2 = %d,\n",i, p1, p2);free(p1);free(p2); }fclose(fp); /*關(guān)閉文件*/ }

??? 在 gcc 的編譯器下面做的測試,

i =0 : p1 = 151765360, p2 = 151765376, // 1 i =1 : p1 = 151765376, p2 = 151765360, i =2 : p1 = 151765360, p2 = 151765376, i =3 : p1 = 151765376, p2 = 151765360, i =4 : p1 = 151765360, p2 = 151765376, i =5 : p1 = 151765376, p2 = 151765360, i =6 : p1 = 151765360, p2 = 151765376, i =7 : p1 = 151765376, p2 = 151765360, i =8 : p1 = 151765360, p2 = 151765376, i =9 : p1 = 151765376, p2 = 151765360, i =10 : p1 = 151765360, p2 = 151765376, i =11 : p1 = 151765376, p2 = 151765360, i =12 : p1 = 151765360, p2 = 151765376, // 1 i =13 : p1 = 151765392, p2 = 151765416, // 2 i =14 : p1 = 151765416, p2 = 151765392, i =15 : p1 = 151765392, p2 = 151765416, i =16 : p1 = 151765416, p2 = 151765392, i =17 : p1 = 151765392, p2 = 151765416, i =18 : p1 = 151765416, p2 = 151765392, i =19 : p1 = 151765392, p2 = 151765416, i =20 : p1 = 151765416, p2 = 151765392, i =21 : p1 = 151765440, p2 = 151765472, i =22 : p1 = 151765472, p2 = 151765440, // 2 。。。。。。。

??? 經(jīng)過筆者的測試,當(dāng) 申請的的空間,從零到12個字節(jié)的時候,兩者的差是16個字節(jié),后序申請的全部的空間差是 8 個字節(jié)。也就是說,實際申請的空間是鏈表頭部 + 申請的空間,同時,8 個字節(jié)是處于內(nèi)存對齊。

參考 : http://blog.csdn.net/misskissc/article/details/17717717

??? (1)malloc(0) :

If size is 0, thenmalloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

根據(jù)官方的解釋,當(dāng)申請的空間為零的時候,返回值要么是為 NULL,要么就可以正確返回一個地址,這個地址被正確釋放。但是實際上,都是返回后者。

??? 根據(jù) malloc 的實現(xiàn)方式,雖然申請的空間為零,但是鏈表的指針也是會被申請一段空間的,所以可以正確申請,空間為 16 字節(jié)(maybe 8字節(jié)) + 0; 而這個鏈表指針地址其實就是 malloc 的返回值的地址。

注意: 對于鏈表維護(hù)空間的大小是16 字節(jié),這個是不確定的,有人說是8個字節(jié),

malloc 與 sizeof:

??? 使用 malloc 是申請了一個程序猿指定的空間,返回值是指向這段空間的的首地址。想要計算這段申請空間的大小,是不可以通過 sizeof 計算出來的:

int *p = (int *)malloc(10 * sizeof(int)); printf("%d\n", sizeof(p));

?

打印出來:

等于4

??? 原因分析,p 是指向申請空間的首地址,也就是說這個是地址,對于指針來說,不論指向的空間是多大,指針占據(jù)的就是四個字節(jié)。所以,sizeof 是不能計算 malloc。

轉(zhuǎn)載于:https://www.cnblogs.com/qxj511/p/4933705.html

總結(jié)

以上是生活随笔為你收集整理的内存的管理方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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