C C 中的記憶體分配機制

2021-06-27 01:13:20 字數 3077 閱讀 1078

本文是總和了其它的幾篇帖子,主要是

一、字串

乙個字元乙個位元組,加上最後的乙個結束符』\0』,其中,strlen函式返回的字串長度不包括』\0』,sizeof操作符返回的位元組長度是包括』\0』的。

二、結構體的儲存

typedef

struct

sample;           sizeof(sample)為1個位元組

typedef

struct

sample;           sizeof(sample)為2個位元組

typedef

struct

sample;               sizeof(sample)為8個位元組,且b是位於離結構體偏移4個位元組的位置

typedef

struct

sample;           sizeof(sample)為12個位元組

typedef

struct

sample;              sizeof(sample)為8個位元組

含有位段的結構體:(位段的各子段是互不影響的,即使旁邊子段超出表示範圍)

typedef

struct

sample;           sizeof(sample)為4個位元組,儘管只使用了4個bit

typedef

struct

sample;            sizeof(sample)為8個位元組

三、c/c++記憶體分配

1.  執行時堆疊(stack)

由編譯器自動分配釋放,存放函式的引數值,區域性變數的值等,其操作方式類似於資料結構中的棧。

2.      堆(heap)

一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶。

3.      全域性靜態區

全域性變數、靜態變數、全域性常量、區域性常量、常量字串均放在這裡,程式結束時由系統收回。

4.      程式**區

存放函式體的二進位制**。

示例:int a = 0; 全域性初始化區

char *p1; 全域性未初始化區

main()

int b;  //棧

char s ="abc";  //棧

char *p2;  //棧

char *p3 ="123456";  //123456為常量字串,在靜態區,p3在棧上。

static int c =0; //全域性(靜態)初始化區

p1 = (char*)malloc(10);

p2 = (char*)malloc(20);  //分配得來得10和20位元組的區域就在堆區。

strcpy(p1,"123456");  //123456為常量字串,在靜態區,編譯器可能會將它與p3所指向的"123456"優化成乙個地方。

四、棧與堆的比較

1.      申請方式

stack:

系統自動進行,只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。

heap:

需要程式設計師自己申請,並指明大小,

在c中malloc函式,如p1 = (char *)malloc(10); 不用時需手動free.

在c++中用new運算子,如p2 = (char *)malloc(10); 不用時需手動delete.

但是注意p1、p2本身是在棧中的。

若最後沒有free則會提示記憶體洩漏。

2.      堆的工作方式

作業系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式的申請時,

會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結 點煉表中刪除,並將該結點的空間分配給程式,另外,對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的delete語句才 能正確的釋放本記憶體空間。另外,由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。

3.      空間大小的限制

棧:在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,在 windows下,棧的大小是2m(也有的說是1m,總之是乙個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。

堆:堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大,但容易產生空間碎片。且也有分配不成功的時候,因此每次分配後應檢查返回的指標是否為空。

4.      存放的內容

堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容有程式設計師安排。

棧:在函式呼叫時第乙個進棧的是主函式中後的下一條指令(函式呼叫語句的下一條可執行語句)的位址然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧,然後是函式中的區域性變數。 注意: 靜態變數是不入棧的。當本次函式呼叫結束後,區域性變數先出棧,然後是引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。

5.      效率對比

堆:char *s1 = "hellow word";是在編譯時就確定的;

棧:char s1 ="hellow word"; 是在執行時賦值的;用陣列比用指標速度要快一些,因為指標在底層彙編中需要用edx暫存器中轉一下,而陣列在棧上直接讀取。

五、關於常量字串的說明

常量字串在靜態區只會有乙份,例:

char

*p = "baixue";

char

*q = "baixue";

void

main()

else

printf("notequal");

}           會輸出列印equal,說明「baixue」這個字串在靜態區只有乙份。

六、malloc/free與new/delete的區別

malloc/free僅僅是申請、釋放指定大小的空間,不做其它事。

new/delete會呼叫物件的構造、析構函式。

C C 記憶體分配機制

1.c語言中的記憶體機制 在c語言中,記憶體主要分為如下5個儲存區 1 棧 stack 位於函式內的區域性變數 包括函式實參 由編譯器負責分配釋放,函式結束,棧變數失效。2 堆 heap 由程式設計師用malloc calloc realloc分配,free釋放。如果程式設計師忘記free了,則會造...

memcached記憶體分配機制

memcached slab allocator分配機制 slab allocator的基本原理是按照預先規定的大小,將分配的記憶體分割成特定長度的塊,以完全解決記憶體碎片問題。slab allocation的原理相當簡單,就是將分配的記憶體分割成各種尺寸的塊 chunk 並把尺寸相同的塊分成組 c...

Memcache記憶體分配機制

1.page 頁 為記憶體分配的最小單位 memcached 的記憶體分配以page為單位,預設情況下乙個page是1m,可以通過 i引數在啟動時指定。如果需要申請記憶體時,memcached會劃分出乙個新的page並分配給需要的slab區域。page一旦被分配在重啟前不會被 或者重新分配 2.sl...