C語言動態(tài)內存規(guī)劃詳解
動態(tài)內存規(guī)劃
用C語言寫程序時,因為語言的一些特性使用數(shù)組的時候只能用常量來申明數(shù)組,就導致數(shù)組的內存被卡得很死,不能根據(jù)我們的實際需求靈活的使用內存空間。有些空間的大小在程序運行時才能知道,那數(shù)組的編譯時開辟空間的方式就不能滿足了,這時候就只有動態(tài)開辟內存
動態(tài)內存函數(shù)的介紹
malloc函數(shù)
void* malloc(size_t size);
這個函數(shù)的 作用是向內存申請一快連續(xù)可用的空間,并返回指向這塊空間的指針。
- 如果開辟成功,則返回一個指向開辟好空間的指針 。
- 如果開辟失敗,則返回一個NULL指針,因此malloc的返回值一定要做檢查
- 返回值的 類型是void*,所以malloc函數(shù)并不知道開辟空間的類型,具體在使用的 時候使用者自己來決定。
- 如果參數(shù)size為0,malloc的行為是標準未定義的,取決于編譯器
free函數(shù)
當我們向內存空間申請的空間 使用完之后一定要用free()函數(shù)將申請的內存空間釋放掉,否則可能會導致內存泄漏
void free(void* ptr)
- 如果參數(shù)ptr指向的空間不是 動態(tài)開辟的,那free函數(shù)的行為是未定義的。
- 如果參數(shù)ptr是NULL指針,則函數(shù)什么事都不用做。
// malloc函數(shù) 和 free函數(shù)的使用語法
#include<stdio.h>
#include<stdlib.h>
int main(){
int* arr = (int*)malloc(sizeof(int)*10); // 因為malloc函數(shù)的返回值是void*所以要進行強制類型轉換
if(arr == NULL){ // 判斷內存是否開辟成功
printf("內存開辟失敗\n");
return;
}
int i = 0;
for(i = 0; i < 10; i++){ // 將數(shù)據(jù)放進我們開辟的空間中
arr[i] = i;
}
for(i = 0; i < 10; i++){
printf("%d",arr[i]); // 驗證數(shù)據(jù)是否放進去了
}
free(arr);// 使用完空間后將它釋放
arr = NULL;
return 0;
}

calloc函數(shù)
C語言還提供了一個函數(shù)叫做calloc,calloc函數(shù)也用來動態(tài)內存分配
void* calloc(size_t num, size_t size);
- 函數(shù)的功能是為 num個大小為size的元素開辟一塊空間,并且把空間的每個字節(jié)初始化為0
- 與函數(shù)malloc的區(qū)別只在于calloc會在返回地址之前把申請的空間的每個字節(jié)初始化為全0
#include<stdio.h>
#include<stdlib.h>
int main(){
int* arr = (int*)calloc(10, sizeof(int));
if(NULL != arr){
int i = 0;
for(i = 0; i < sizeof(int)*10; i++){
printf("%d ",*((char*)arr+i));
}
}
free(arr);
arr = NULL;
return 0;
}

realloc函數(shù)
realloc函數(shù)的出現(xiàn)讓動態(tài)內存管理更加靈活,有時我們會發(fā)現(xiàn)之前申請的空間太小了不夠用,有時也會覺得申請的空間太大用不了那么多。為了能夠更加靈活的管理內存我們可以使用realloc函數(shù)對開辟的內存空間進行調整
void* realloc(void* ptr, size_t size);
- ptr是要調整的內存地址
- size是調整之后新的內存大小
- 這個函數(shù)調整原內存空間大小的基礎上,還會將原來內存中的數(shù)據(jù) 移動到新的空間
- realloc在調整內存空間的內存時有兩種情況,**第一種情況:**原有空間之后足夠大的空間,這時會在原有空間之后的連續(xù)空間開辟新的空間。**第二種情況:**原有的空間之后沒有足夠大空間,這種情況是在堆空間上另找一個合適大小的連續(xù)空間來使用,這樣函數(shù)返回的是一個新的內存地址。所以在用realloc函數(shù)調整空間的時候需要用一個臨時指針變量來存放realloc的返回值,再把變量有賦值給之前的指針變量
#include<stdio.h>
#include<stdlib.h>
int main(){
int* arr = (int*)malloc(sizeof(10));
if(NULL != arr){
// 業(yè)務處理
}
// 當開辟的空間用完時
int* tmp = (int*)realloc(arr, sizeof(int)*20);
if(NULL != tmp){
arr = tmp;
}
return 0;
}
柔性數(shù)組
typedef struct arr_type{
int i;
int a[]; // 柔性數(shù)組成員
}type_arr;
- 結構體中的柔性數(shù)組成員前面必須至少有一個其他成員。
- sizeof返回的 這種結構大小不包括柔性數(shù)組的內存。
- 包含柔性數(shù)組成員的結構用malloc函數(shù)進行 內存的動態(tài)分配,并且分配的內存應該大于結構的大小,以適應柔性數(shù)組的預期大小
typedef struct arr{
int i;
int a[];
}arr;
printf("%d\n",sizeof(arr));// 輸出的是4
柔性數(shù)組的使用
int main() {
struct rou_arr* ps = (struct rou_arr*)malloc(sizeof(int) + 10 * sizeof(int));
if (ps == NULL) {
printf("%s", strerror(errno));
}
ps->i = 10;
int i = 0;
for (i = 0; i < 10; i++) {
ps->arr[i] = i;
}
for (i = 0; i < 10; i++) {
printf("%d ", ps->arr[i]);
}
// 對柔性數(shù)組進行擴容
struct rou_arr* ptr = (struct rou_arr*)realloc(ps, sizeof(int) + sizeof(int) * 20);
if (ptr == NULL) {
printf("realloc is failure\n");
return -1;
}
ps = ptr;
for (i = 0; i < 20; i++) {
ps->arr[i] = i;
}
for (i = 0; i < 20; i++) {
printf("%d ", ps->arr[i]);
}
return 0;
}
柔性數(shù)組的好處有兩個,一是方便內存釋放,二是有利于訪問速度
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
C++簡單實現(xiàn)RPC網(wǎng)絡通訊的示例詳解
RPC是遠程調用系統(tǒng)簡稱,它允許程序調用運行在另一臺計算機上的過程,就像調用本地的過程一樣。本文將用C++簡單實現(xiàn)RPC網(wǎng)絡通訊,感興趣的可以了解一下2023-04-04

