您現在的位置是:首頁 > 綜合
C語言:3分鐘看懂 malloc
- 由 不會程式設計的程式圓 發表于 綜合
- 2022-04-12
return0是什麼意思
如果對你有幫助,請不吝惜你的小手給我點個贊支援下作者!關注我不迷路
初識 動態記憶體分配 [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]
,但是很遺憾,每次編譯器都把你扼殺在程式編譯之前!
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;
}
什麼?不是改進嗎?怎麼行數反而變多了?
測測你能給系統分配多大空間?
#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
檢視答案哦
歡迎各位與我交流討論!
如果對你有幫助,請不吝惜你的小手給我點個贊支援下作者!關注我不迷路