C 基礎之程式記憶體分配方式

2021-10-05 02:31:41 字數 3069 閱讀 3427

目錄:

程式記憶體布局

程式驗證

棧與堆的比較

申請後系統的響應

申請效率的比較

申請大小的限制

堆和棧中的儲存內容

棧與堆的區別

現在的應用程式都執行在乙個虛擬記憶體空間裡,以32位系統為例,其定址空間為 4g,大部分的作業系統都將4g記憶體空間的一部分挪給核心呼叫,應用程式無法直接訪問這一段記憶體,這一部分核心位址成為核心態空間,linux預設將高位址的1g空 間分配給核心,使用者使用剩下的3g空間成為使用者態空間,使用者態空間一般有如下預設區域:

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

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

全域性/靜態區(static)全域性變數靜態變數的儲存是放在一塊的,在程式編譯時分配

文字常量區:存放常量字串

程式**區:存放函式體(類的成員函式、全域性函式)的二進位制**

虛擬記憶體空間示意圖如下:

如下:

int a =0;

//全域性變數,全域性區,預設初始化為0

char

*p1;

//全域性變數,全域性區, null

intmain()

為了更直觀一點,我們把位址都列印出來

#include

#include

#include

using std::cout;

using std::endl;

int val1;

//全域性變數,全域性區,預設初始化為0

char

*p1;

//全域性變數,全域性區,預設null

intmain()

linux 和 window 下列印結果進行對比

linux

window(vs2017 64位)

列印變數的位址

列印變數的位址

全域性變數

全域性變數

&val1 = 0x555e8f11b018

&val1 = 0056a2d0

val1 = 0

val1 = 0

&p1 = 0x555e8f11b020

&p1 = 0056a2d4

p1 = (nil)

p1 = 00000000

&val2 = 0x7ffcd6a59b24

&val2 = 012ffe8c

val2 = 32564

val2 = -858993460

&p2 = 0x7ffcd6a59b28

&p2 = 012ffe80

p2 = (nil)

p2 = cccccccc

&str = 0x7ffcd6a59b41

&str = 012ffe70

&val3 = 0x555e8f11b02c

&val3 = 0056a2d8

&pstr = 0x7ffcd6a59b30

&pstr = 012ffe64

pstr = 0x555e8ef19c19

pstr = 00567be8

&hello,world = 0x555e8ef19c19

&hello,world = 00567be8

&p3 = 0x7ffcd6a59b38

&p3 = 012ffe58

p3 = 0x555e9054f280

p3 = 017764c0

main = 0x555e8ef1988a

main = 00561320

申請後系統的響應

申請效率的比較:

申請大小的限制

堆和棧中的儲存內容

棧與堆的區別

棧與堆的區別在一下六個方面有所不同:區別棧

管理方式不同由編譯器自動管理,無需我們手工控制

釋放工作由程式設計師控制,容易產生memory leak

空間大小不同一般都是有一定的空間大小的,例如,在vs下,預設的棧空間大小是1m

一般來講在32位系統下,記憶體可以達到4g的空間,從這個角度來看堆記憶體幾乎是沒有什麼限制的。

分配方式不同棧的動態分配由編譯器進行釋放,無需我們手工實現。

堆是動態分配的,沒有靜態分配的堆。靜態分配是編譯器完成的,比如區域性變數的分配。動態分配,由malloc, calloc函式進行分配,

生長方向不同生長方向是向下的,是向著記憶體位址減小的方向增長。

生長方向是向上的,也就是向著記憶體位址增加的方向

碎片問題不同對於棧來講,不會存在大量的碎片問題,因為棧是先進後出的,他們是如此的一一對應,以至於永遠都不可能有乙個記憶體塊從棧中間彈出,在他彈出之前,在它上面的後進的棧內容已經被彈出。

對於堆來講,頻繁的new/delete勢必會造成記憶體空間的不連續,從而造成大量的碎片,使程式效率降低。

C記憶體分配方式與C 記憶體分配方式

c記憶體分配方式 注 malloc函式的實質體現在,它有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二 一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組 接下來,將分配...

C 記憶體分配方式

在c 中,記憶體分成5個區 堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區。棧 就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數 函式引數等。在乙個程序中,位於使用者虛擬位址空間頂部的是使用者棧,編譯器用它來實現函式的呼叫。和堆一樣,使用者棧在程...

C 記憶體分配方式

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數名,區域性變數的名等。其操作方式類似於資料結構中的棧。2 堆區 heap 由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結構中的堆是兩回事,分配方式倒是類似於...