int val = 20; // 在棧空間上開闢四個位元組
char arr[10] = ; //在棧空間上開闢10個位元組的連續空間
上述開闢空間的方式有兩個特點:
空間開闢大小是固定的;
陣列在申明的時候,必須指定陣列的長度,它需要的內存在編譯時分配;
但對與空間的需求,有時需要的空間大小在程式執行的時候才能知道,所以需要動態開闢空間了;
程式記憶體分配的幾個區域:
棧區(stack):再執行函式時,函式內區域性變數的儲存單位都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。棧區主要存放執行函式而分配的區域性變數、函式引數、返回資料、返回位址等;
堆區(heap):一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能有os**。分配方式類似於鍊錶;
資料段(靜態區)(static):存放全域性變數、靜態資料。程式結束後由系統釋放;
**段:存放函式體(類成員函式和全域性函式)的二進位制**;
void* malloc(size_t size);
malloc函式向記憶體申請一塊連續可用的空間,並返回指向這塊空間的指標;
如果開闢成功,則返回乙個指向開闢好空間的指標;
如果開闢失敗,則返回乙個null指標,因此malloc的返回值一定要做檢查;
返回值的型別是void*,所以malloc函式並不知道開闢空間的型別,具體在使用的時候使用者自己來決定;
當記憶體不再使用時,應使用free()函式將記憶體塊釋放;
如果引數size為0,malloc的行為標準是未定義的,取決於編譯器;
另外乙個函式free(),專門是用來做動態記憶體的釋放和**的,如下:
void free(void* ptr);
free函式是用來釋放動態開闢的記憶體;
如果引數ptr指向的空間不是動態開闢的,那free函式的行為是未定義的;
如果引數ptr是null指標,則函式什麼事都不做;
malloc和free都宣告在stdlib.h標頭檔案中。
#include#includeint main()
free(p);//釋放p所指向的動態記憶體
//free(p)是只是將malloc申請的記憶體空間釋放,在不改變free()函式的原型前提下
//是無法做到p=null的,p=null相當於空指標,不指向任何有效的物件;
p = null;//此處將p置空,有必要
//使用new或者malloc申請了指標p,使用後delete或者free,你必須將指標值設定為null,
//否則,p將成為乙個非法指標,後續**如果使用到該指標有可能會造成系統崩潰或者破壞自身有效記憶體資料
system("pause");
return 0;
}
void* calloc(size_t num,size_t size);
函式的功能是為num個大小為size的元素開闢一塊空間,並且把空間的每個位元組初始化為0;
calloc與函式mallo的區別不做初始化,分配到的空間中的資料是隨機資料;
#include#includeint main()
free(p);
p = null;
system("pause");
return 0;
}
void* realloc(void* ptr,size_t size);
realloc函式讓動態記憶體管理更加靈活;
realloc函式可以做到對動態開闢記憶體大小的調整;
ptr是要調整的記憶體大小,size是調整之後新大小,返回值為調整之後的記憶體起始位置;
函式調整原記憶體空間大小的基礎上,還會將原來記憶體中的資料移動到新的空間;
realloc調整記憶體空間存在兩種情況:(1)原有空間之後有足夠大的空間,此時直接在原有記憶體之後直接追加空間,原有空間的資料不發生變化;(2)原有空間之後沒有足夠大的空間,此時在堆空間上另找乙個合適大小的連續空間來使用,函式返回的是乙個新的記憶體位址;
#include#includeint main()
對動態開闢空間的越界訪問不一定報錯;
不能使用free釋放一塊動態記憶體開闢的一部分,如:
int main()
不能對非動態開闢記憶體使用free釋放,如:
int main()
不能對同一塊動態記憶體多次釋放;
忘記釋放不再使用的動態開闢的空間會造成記憶體洩漏;
切記:動態開闢的空間一定要釋放,並且正確釋放;
什麼是柔性陣列?
結構中的最後乙個元素允許是未知大小的陣列,這就叫做「柔性陣列」成員。
typedef struct st_type
type_a;
柔性陣列的特點:
結構中的柔性陣列成員前面必須至少乙個其他成員;
sizeof返回的這種結構大小不包括柔性陣列的記憶體;
包含柔性陣列成員的結構用malloc()函式進行記憶體的動態分配,並且分配的記憶體應該大於結構的大小,以適應柔性陣列的預期大小;
typedef struct st_type
type_a;
pritnf("%d\n",sizeof(type_a));//輸出為4
//柔性陣列的使用
int main()
free(p);
return 0;
}
動態記憶體管理
首先應該明白物件的三種內部的儲存方式 自動儲存,靜態儲存,和動態儲存。當執行離開當期程式塊的時候,堆疊指標返回到它進入程式塊 之前的地方,有效的銷毀了那個程式塊的自動變數。重新進入這個塊會再次建立所有的自動變數。靜態物件宣告或者在檔案域中。動態物件是存在系統呼叫 的在執行期中建立並且儲存在堆中,這是...
動態 記憶體管理
定義變數時,必須制定其資料型別和名字。而動態建立物件時,只需指定其資料型別,而不必為該物件命名。取而代之的是,new表示式返回指向新建立物件的指標,我們通過該指標來訪問此物件。int i int pi new int 這個new表示式在自由儲存區中分配建立了乙個整型物件,並返回此物件的位址,並用該位...
動態記憶體管理
c語言使用malloc calloc realloc free進行動態記憶體管理。void test c 通過new和delete動態管理記憶體。new delete動態管理物件。new delete動態管理物件陣列。void test void test int globalvar 1 stati...