宣告:棧區空間的介紹我就不陳述了,下面幾句話是在別人在網上的總結。
棧空間是由系統自動分配,速度較快。在linux下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的。
棧中存放函式的引數值,區域性變數的值等,堆區是向上增長的用於分配程式設計師申請的記憶體空間。另外還有靜態區是分配靜態變數,全域性變數空間的;唯讀區是分配常量和程式**空間的;以及其他一些分割槽。
由於棧的大小有限,所以用子函式還是有物理意義的,而不僅僅是邏輯意義。
棧: 在函式呼叫時,第乙個進棧的是主函式中函式呼叫後的下一條指令(函式呼叫語句的下一條可執行語句)的位址,然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧的,然後是函式中的區域性變數。注意靜態變數是不入棧的。
只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。
在棧區申請記憶體時,記憶體空間是從高位址向低位址逐個分配的,後定義的變數存在前乙個變數位址的後面(連續的,但是編譯器會自動分配變數間間隔,其大小取決於編譯器。連續定義的變數可能沒有間隔)。
定義變數時採用空間對其的策略,對其長度會選擇所有變數中最長的型別為最大長度。當分配的空間不足最大長度時,低位位址將被空閒出來,當後面申請的空間小於等於所剩空間時可接著上次空間結束位址宣告(沒變數間隔時),但是當所要宣告空間比所剩餘空間大時,將留下剩餘空間,往後自動對其。
#pragma pack(n) //設定對其基數函式的引數和區域性變數儲存在棧區中。#pragma pack(0) //取消對其基數
函式的引數和區域性變數一樣,採用從高位址向低位址逐個分配空間。但是並沒有和呼叫此函式的工作區空間相連,函式引數和變數在其低位址。
函式中,引數和區域性變數也不相連,被變數間隔分開了,引數在低位址。
void main()函式呼叫完就會銷毀記憶體,等其他函式使用void fun2(int a,int b,int c)
在棧區空間用指標訪問時不能修改越界的記憶體
但是堆中反而可以,可能是malloc分配的記憶體前面存放該記憶體的大小,後面是空閒記憶體塊(可能會被malloc呼叫分配出去)
int * a = 4;在棧區空間用指標訪問時,指標指向改變後,不能正確讀出位址存在的資料,前後有 『&』 讀取過位址後,才能成功讀取資料(此時位址相同),沒有讀取過位址時,該位址空間不能正確訪問,儘管定義順序如此。*(a+1) = 8;//錯誤int *p = (int *)malloc(sizeof(int));
*(p+1) = 9;//可以使用,但不建議。*(p-1) = 9;//錯誤
定義 a,b,c 但是讀取過a,c位址,沒讀取過b位址,此時c位址在a的後面挨著.
int a =1;整型和字元型沒有變數間隔,字串存在變數間隔,形參和區域性變數有間隔。int b = 2;
int c = 3;
&a,&c;
printf("%p %p\n",&a,&c); // 0x7ffc3695e49c 0x7ffc3695e498
記憶體分配空間中的堆區和棧區的區別
在c語言中,記憶體分配的空間一般分為六個區。常量 區 資料段區 bss段 堆空間 棧空間以及記憶體空間。記憶體空間是從下向上增長的。1 常量區 用來存放 和常量 2 資料段 用來存放初始化的靜態變數和全域性變數 3 bss段 用來存放未初始化的靜態變數和全域性變數 4 堆空間 動態malloc申請的...
討論下記憶體空間分配在堆區,棧區不同點
str所指向的記憶體空間能修改才行,否則會報錯 int trimspace2 char str int isspace int c 函式說明 檢查引數c是否為空格字元 是 返回true 1 while isspace p i p i 0 while isspace p j p j 0 ncount ...
如何讓類物件只在棧(堆)上分配空間?
一般情況下,編寫乙個類,是可以在棧或者堆分配空間。但有些時候,你想編寫乙個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想想,其實也是可以滴。在c 中,類的物件建立分為兩種,一種是靜態建立,如a a 另一種是動態建立,如a ptr new a 這兩種方式是有區別的。1 靜態建立類物件 是...