您現在的位置是:首頁 > 綜合

C語言:3分鐘看懂 malloc

  • 由 不會程式設計的程式圓 發表于 綜合
  • 2022-04-12
簡介可以這麼做:int* arr = (int*)malloc(sizeof(int) * N)sizeof(int)代表陣列中每個元素的型別N代表陣列的元素個數所以malloc的意義是向 堆區 要了一塊sizeof(int) * N這麼大的空

return0是什麼意思

如果對你有幫助,請不吝惜你的小手給我點個贊支援下作者!關注我不迷路

C語言:3分鐘看懂 malloc

初識 動態記憶體分配 [C語言必知必會]

動態記憶體分配的引入

初學陣列的時候,有一個問題經常困擾著我,就是:我們可不可以

自己在程式裡定義一個數組的大小

而不是在函式開頭先宣告一個很大的陣列,然後僅僅使用它的一小部分?

請看下面的程式:

我們需要一個大小為 N ( N < 1000)的陣列,我們通常這麼寫:

intmain(void){

int arr[1000] = { 0 };

int N = 0;

int i = 0;

printf(“請輸入陣列的大小\n”);

scanf(“%d”, &N);

printf(“請輸入%d個數\n”, N);

for (i = 0; i < N; i++)

scanf(“%d”, &arr[i]);

return0;

}

每次這麼寫我都覺得自己在繞遠路,為什麼就不能直接把輸入的變數 N 當作陣列的大小直接使用?

比如這樣:

arr[N]

,但是很遺憾,每次編譯器都把你扼殺在程式編譯之前!

C語言:3分鐘看懂 malloc

C99才可以用變數做陣列定義的大小

並且可以在程式中隨時宣告變數。(C99前我們需要在函式的最前面的區域對所有變數進行宣告)

如果我不想用上面那種笨笨的辦法,又沒有支援C99的編譯器,我該怎麼辦?

可以這麼做:

int* arr = (int*)malloc(sizeof(int) * N)

sizeof(int)

代表陣列中每個元素的型別

N

代表陣列的元素個數

所以malloc的意義是向 堆區 要了一塊

sizeof(int) * N

這麼大的空間

malloc 與 free ——好哥倆

malloc

標頭檔案

stdlib

原型

void* malloc(size_t size)

所以需要根據實際你需要的型別對其強制型別轉換

返回值

成功時,返回指向新分配記憶體的指標。為避免記憶體洩漏,必須用 free() 或 realloc() 解分配返回的指標。

失敗時,返回空指標(NULL)

引數

:size - 要分配的位元組數

定義

分配 size 位元組的未初始化記憶體。

若分配成功,則返回為任何擁有基礎對齊的物件型別對齊的指標。

若 size 為零,則 malloc 的行為是實現定義的。例如可返回空指標。亦可返回非空指標;但不應當解引用這種指標,而且應將它傳遞給 free 以避免記憶體洩漏。

更多關於malloc

https://zh。cppreference。com/w/c/memory/malloc

free

標頭檔案

stdlib

原型

void free( void* ptr );

引數

:指向要解分配的記憶體的指標

返回值

:無

此函式接收空指標(並對其不處理)以減少特例的數量。不管分配成功與否,分配函式返回的指標都能傳遞給 free()

這是什麼意思?意思就是malloc與free成對出現,不要忘記寫free哦。

定義:

解分配之前由 malloc() 、 calloc() 、 aligned_alloc (C11 起) 或 realloc() 分配的空間。

若 ptr 為空指標,則函式不進行操作

。[1]

若 ptr 的值 不等於之前從 malloc() 、 calloc() 、 realloc() 或 aligned_alloc() (C11 起) 返回的值

[2],則行為未定義。

若 ptr 所指代的記憶體區域已經被解分配[3]

,則行為未定義,即是說已經以ptr 為引數呼叫 free() 或 realloc() ,而且沒有後繼的 malloc() 、 calloc() 或 realloc() 呼叫以 ptr 為結果。

若在 free() 返回後透過指標 ptr 訪問記憶體[4]

,則行為未定義(除非另一個分配函式恰好返回等於 ptr 的值)。

更多關於free

https://zh。cppreference。com/w/c/memory/free

free()

:將申請來的空間的

首地址

還給“系統”,只要申請到了空間就

一定要歸還

畢竟有借有還,再借不難嘛

解讀 free

註釋1:釋放空指標有何意義?

我們在宣告一個指標時,一般把它初始化為0,也就是NULL。

這樣做的好處是,如果我們在後面的程式中沒有讓這個指標指向一塊具體的空間,這個指標不會是野指標,方便我們用來判斷。比如

if(p != NULL)

我們還知道,當malloc失敗時返回的是 NULL

所以我們一開始寫上free是好習慣,因為我們不知道我們會不會用到我們宣告的指標,也不知道malloc能不能成功

這時候,free空指標就是有意義的了

註釋2:molloc申請到的指標 與 free要釋放的指標保持一致

#include

intmain(){

int* p;

p = (int*)malloc(100 * 1024);

p++; //改變了 p 的首地址;

free(p);//free 沒有得到 malloc時 分配給p的首地址,程式崩潰

return0;

}

註釋3:free釋放空間後,被釋放的指標成為野指標,不能直接使用它

#include

intmain(){

int* p;

p = (int*)malloc(100 * 1024);

p++;

free(p);

p++;//free 釋放後 p 成為了野指標,程式崩潰

return0;

}

註釋4:不能多次釋放同一次malloc申請的地址

#include

intmain(){

int* p;

p = (int*)malloc(100 * 1024);

p++;

free(p);

free(p);

return0;

}

現在我們就可以改進我們上面的程式啦!

#include

intmain(void){

int i = 0;

int N = 0;

int* arr;

printf(“請輸入陣列的大小\n”);

scanf(“%d”, &N);

arr = (int*)malloc(sizeof(int) * N);

printf(“請輸入%d個數\n”, N);

for (i = 0; i < N; i++)

scanf(“%d”, &arr[i]);

free(arr);

return0;

}

什麼?不是改進嗎?怎麼行數反而變多了?

C語言:3分鐘看懂 malloc

測測你能給系統分配多大空間?

#include

intmain(void){

void* p;

int i = 0;

//每次申請100M,失敗返回空指標0,退出迴圈

while ((p = malloc(1024 * 1024 * 100)))

i++;

printf(“最多分配%d00M記憶體”, i);

return0;

}

如果忘記了free?

我們一次程式中可以申請的記憶體是有限的。

如果你只是平時寫簡單的程式,寫完就關閉,退出去了,這時忘記了free的話,不會對任何人造成影響,因為作業系統有清除曾使用的記憶體的機制

但是如果是一個持續執行的伺服器呢?堆區中所有的空間都被你申請了呢?

free的常見問題

申請了沒有free -> 長時間執行記憶體逐漸下降

free 後再free

地址變更後,直接去free

小測試:

1。對於以下的程式碼段,正確的說法是:

char *p;

while(1){

p = malloc(1);

*p = 0;

}

A:最終程式會因為沒有空間了而退出

B:最終程式會因為向0地址寫入而退出

C:程式會一直執行下去

D:程式不能被編譯

2。對於以下程式碼段:

int a[] = {1, 2, 3, 4, 5};

int *p = a;

int *q = &a[5];

printf(“%d”,q-p);

sizeof(int) = 4

時,以下說法正確的是:

A:因為第三行的錯誤不能編譯

B:因為第三行的的錯誤執行時崩潰

C:輸出5

D:輸出20

3。使用malloc就可以做出執行時可以隨時改變大小的陣列

A:√

B:

後臺回覆:

2020 0204

檢視答案哦

歡迎各位與我交流討論!

如果對你有幫助,請不吝惜你的小手給我點個贊支援下作者!關注我不迷路

Top