C中動態記憶體管理 堆中分配記憶體

2021-10-01 15:58:10 字數 3914 閱讀 1244

堆區

標頭檔案:#include
1).malloc()函式會向堆中申請一片連續的可用記憶體空間

2).若申請成功 ,,返回指向這片記憶體空間的指標 ,若失敗 ,則會返回null, 所以我們在用malloc()函式開闢動態記憶體之後, 一定要判斷函式返回值是否為null.

3).返回值的型別為void*型, malloc()函式並不知道連續開闢的size個位元組是儲存什麼型別資料的 ,所以需要我們自行決定 ,方法是在malloc()前加強制轉 ,轉化成我們所需型別 ,如: (int*)malloc(sizeof(int)*n).

4).如果size為0, 此行為是未定義的, 會發生未知錯誤, 取決於編譯器

free(p);

p=null;

在堆中申請的記憶體空間不會像在棧中儲存的區域性變數一樣 ,函式呼叫完會自動釋放記憶體 , 如果我們不手動釋放, 直到程式執行結束才會釋放, 這樣就可能會造成記憶體洩漏, 即堆中這片記憶體中的資料已經不再使用, 但它一直佔著這片空間, (通俗說就是就是佔著茅坑不拉屎), 所以當我們申請的動態記憶體不再使用時 ,一定要及時釋放 .

1).如果ptr沒有指向使用動態記憶體分配函式分配的記憶體空間,則會導致未定義的行為。

2).如果ptr是空指標,則該函式不執行任何操作。

3).此函式不會更改ptr本身的值,因此它仍指向相同(現在已經無效)的位置(記憶體)

4).在free()函式之後需要將ptr再置空 ,即ptr = null;如果不將ptr置空的話 ,後面程式如果再通過ptr會訪問到已經釋放過無效的或者已經被**再利用的記憶體, 為保證程式的健壯性, 一般我們都要寫ptr = null; .

/*

#include #include int main()

printf("申請的記憶體空間大小為:%d\n", size);

p = (int *)realloc(p, sizeof(int) * 100);

size = _msize(p);

printf("重新申請的記憶體空間大小為:%d", size);

free(p);

return 0;}*/

#include // for _max_path definition

#include int main()

return 0;

}

執行結果:

與malloc()函式的區別只在於,calloc()函式會在返回位址之前將所申請的記憶體空間中的每個位元組都初始化為0.

1).calloc()函式功能是動態分配num個大小(位元組長度)為size的記憶體空間。

2).若申請成功 ,,返回指向這片記憶體空間的指標 ,若失敗 ,則會返回null, 所以我們在用calloc()函式開闢動態記憶體之後, 一定要判斷函式返回值是否為null。

3).返回值的型別為void*型, calloc()函式雖然分配num個size大小的記憶體空間 ,但還是不知道儲存的什麼型別資料 ,所以需要我們自行決定 ,方法是在calloc()前加強制轉 ,轉化成我們所需型別 ,如: (int*)calloc(num, sizeof(int))。

4).如果size與num有乙個或都為0, 此行為是未定義的, 會發生未知錯誤, 取決於編譯器。

/*

#include #include int main()

printf("申請的記憶體空間大小為:%d\n", size);

p = (int *)realloc(p, sizeof(int) * 100);

size = _msize(p);

printf("重新申請的記憶體空間大小為:%d", size);

free(p);

return 0;}*/

#include // for _max_path definition

#include int main()

//輸出char *p的內容

printf("%s\n", *p);

free(p);

p = null;

printf("記憶體釋放成功\n");

return 0;

}

執行結果:

realloc()函式讓動態記憶體管理更加靈活 .在程式執行過程中動態分配記憶體大小,  如果分配的太大 ,則浪費空間, 如果太小, 可能還是會出現不夠用的情況 .為了合理的利用記憶體,我們一定會對記憶體的大小做靈活的調整。那realloc() 函式就可以做到對動態開闢記憶體大小的調整(既可以往大調整, 也可以往小了調整) .

1).ptr為需要調整的記憶體位址

2).size為調整後需要的大小(位元組數)

3).若調整成功, 返回值為調整大小後記憶體的起始位置(也就是指向調整後記憶體的指標), 若失敗(當沒有記憶體可以分配時, 一般不會出現), 則返回null, 所以還是要對返回值判空

4).如果ptr是空指標, 則和calloc()函式一樣作用一樣

注意 : realloc()函式在擴大記憶體空間時有兩種情況

1).ptr所指的記憶體後有足夠的記憶體空間用來擴充套件 ,如圖 :

2).ptr所指記憶體後沒有足夠的空間來擴充套件 ,如圖 :

當第二種情況時, 若申請新的記憶體空間成功, 會將ptr所指向的記憶體中的內容拷貝到新的記憶體空間中, ptr所指向的記憶體會被釋放, 返回新得記憶體位址, 若不成功 ,ptr 所指記憶體不會被釋放, 函式返回null

1).malloc()和calloc()函式用法一樣, 唯一的區別是calloc()會對所申請記憶體的每個位元組初始化為0

2).malloc(), calloc(), realloc()申請的記憶體不再使用時 ,一定要用free()釋放 ,否則會造成記憶體洩漏

3).p = realloc(ptr, size)函式返回值不為空時, 釋放記憶體時不需寫free(ptr) ,只需寫free(p) 

參考:c語言動態記憶體分配函式

c 記憶體管理

什麼是野指標?野指標就是指標指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)!

1、指標變數在定義時未初始化:

int *p;            //定義之後未初始化是乙個野指標

printf("%d",*p);

2、釋放完指標所指向的記憶體之後未置空

int *p = (int*)malloc(sizeof(int));

free(p); //釋放完之後未置空 p=null;

printf("%d",*p);

怎麼辦?

初始化時置 null

int *p=null;
釋放時置null

free(p);

p=null;

指標 堆記憶體分配(動態記憶體)

一 對於普通陣列來說,在定義或初始化時必須確定元素個數,即下標必須是已知的,即在編譯時已知。例 定義陣列時 int a 6 初始化陣列時,float a 對陣列a來說,雖然沒有下標,但是通過 中的元素個數,可以查出其下標為4。像這樣的格式 int a 錯誤,下標未知 int a n 錯誤,同上 in...

C語言記憶體管理 動態記憶體分配

一 介紹 一般定義陣列是要給固定的長度,當我們不知道輸入的長度是多少的時候,怎麼辦 例如 需求現在有乙個 本儲存,本中聯絡人並不知道有多少,一次定義1000個長度會占用記憶體,定義太小又會導致儲存不夠 c語音給了一種特殊的方式,動態記憶體分配 二 函式介紹 標頭檔案 include 1 void m...

c語言動態記憶體分配 C 動態記憶體分配

動態記憶體分配 雖然通過陣列就可以對大量的資料和物件進行有效地管理,但是很多情況下,在程式執行之前,我們並不能確切地知道陣列中會有多少個元素。這種情況下,如果陣列宣告過大,就會造成浪費 宣告過小,就會影響處理。在c 中,動態記憶體分配技術可以保證程式在執行過程中按照需要申請適量記憶體,使用後釋放,從...