摘要:一動態內存的函數和頭文件功能向堆區申請一塊大小為的連續的空間,并返回該空間的起始地址。若指向的不是動態分配的內存,函數的行為標準未定義,取決于編譯器。
??? 常規開辟空間的方式,開辟出空間的大小是固定的(尤其是數組的開辟需要預先給定空間),而動態內存分配可以解決這個問題。
1?? malloc:
void* malloc (size_t size);
??? 頭文件: stdlib.h
??? 功能:向堆區申請一塊大小為size
的連續的空間,并返回該空間的起始地址。
NULL
。?注意:
??? ① 返回值的類型是 void*
,所以malloc
函數并不知道開辟空間的類型,具體在使用的時候使用者自己來決定。
//eg.int* p = (int*)malloc(40);//強制類型轉換為int*
??? ② 如果參數 size
為0
,malloc
的行為是標準是未定義的,取決于編譯器。
2?? free:
void free (void* ptr);
??? 功能:釋放動態開辟的內存。
?注意:
??? ① 若ptr
指向的是NULL
,函數啥也不做。
??? ② 若ptr
指向的不是動態分配的內存,free
函數的行為標準未定義,取決于編譯器。
//egint main(){ int num = 0; scanf("%d", &num); int* ptr = NULL; ptr = (int*)malloc(num * sizeof(int));//動態開辟空間 if (NULL != ptr)//是否開辟成功 { int i = 0; for (i = 0; i < num; i++) { *(ptr + i) = 0; } } free(ptr);//釋放ptr所指向的動態內存 //雖然free將空間釋放但是ptr還可以找到那塊空間,所以需要將ptr置NULL ptr = NULL; return 0;}
Summary:
malloc
與free
是一對,malloc
開辟后需要檢測是否成功,free
釋放后需要置NULL
。
void* calloc (size_t num, size_t size);
??? 功能:向堆區申請num
個大小為size
的空間,并將空間的每一個字節初始化為0
,返回該空間的起始地址。
//eg.int main(){ int* p = (int*)calloc(10, sizeof(int)); if (NULL != p) { //使用空間 } free(p); p = NULL; return 0;}
void* realloc (void* ptr, size_t size);
??? 功能:將ptr
指向的空間調整為size
大小,返回調整之后的內存起始位置。
?注意:有兩種調整內存空間的情況:
??? ① 原有空間之后有足夠大的空間:在原有空間的基礎上向后延伸,不改變原有數據。
??? ② 原有空間之后沒有足夠大的空間:在堆區上找一個連續的合適空間,返回新空間的起始地址。并將數據轉移到新地址中,舊地址釋放。
//eg.int main(){ int* ptr = (int*)malloc(100); if (ptr != NULL) { //業務處理 } else { exit(EXIT_FAILURE); //EXIT_FAILURE 可以作為exit ()的參數來使用,表示沒有成功地執行一個程序 //EXIT_SUCCESS 作為exit ()的參數來使用,表示成功地執行一個程序 } //擴容 int* p = NULL; p = realloc(ptr, 1000);//要注意需要新建一個變量以免開辟失敗而造成原地址丟失 if (p != NULL) { ptr = p; } free(ptr); ptr = NULL; return 0;}
Summary:
所有動態內存開辟后,最好都檢測一遍是否成功,釋放后都置NULL
。
在堆區申請的空間,有兩種回收方式
- free
- 程序退出時,申請的空間被回收
//Qvoid test(){ int* p = (int*)malloc(INT_MAX / 4); *p = 20;//如果p的值是NULL,就會有問題 free(p); p=NULL;}
//Svoid test(){ int* p = (int*)malloc(INT_MAX / 4); if (p == NULL)//檢測是否開辟成功 { exit(EXIT_FAILURE); } *p = 20; free(p); p=NULL;}
//Qvoid test(){ int* p = (int*)malloc(100); if (NULL != p) { *p = 20; }}int main(){ test(); while (1);}
S:開辟的空間在未結束前,一直被占用,記得free
回收,別等程序退出自己回收。
//Qvoid test(){ int i = 0; int* p = (int*)malloc(10 * sizeof(int)); if (NULL == p) { exit(EXIT_FAILURE); } for (i = 0; i <= 10; i++) { *(p + i) = i;//當i是10的時候越界訪問 } free(p); p=NULL;}
S:編譯器不能檢測出,得程序員自己格外注意。
//Qvoid test(){ int a = 10; int* p = &a; free(p);//err p=NULL;}
S:free
釋放堆上的空間
void test(){ int* p = (int*)malloc(100); p++;//p不再指向動態內存的起始位置 free(p);//err}
free
釋放一塊空間必須提供該空間的起始地址。
//Qvoid test(){ int *p = (int *)malloc(100); free(p); free(p);//err 重復釋放}
//Svoid test(){ int *p = (int *)malloc(100); free(p); p=NULL; free(p);//NULL啥都不干 p=NULL;}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/122558.html
摘要:棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。棧區主要存放運行函數而分配的局部變量函數參數返回數據返回地址等。 C語言動態內存分配篇 目錄 一、為什么存在動態內存管理/分配? ????????內存的存儲形式劃分 二、動態內存函數的介紹 ????????malloc ...
摘要:本文主要介紹的數據結構簡單動態字符串簡稱。遵守字符串以空字符串結尾的慣例,保存的空字符串一個字節空間不計算在的屬性里面。添加空字符串到字符串末尾等操作,都是由函數自動完成的,所以這個空字符對于使用者來說完全是透明的。Redis是用ANSI C語言編寫的,它是一個高性能的key-value數據庫,它可以作用在數據庫、緩存和消息中間件。其中 Redis 鍵值對中的鍵都是 string 類型,而鍵...
摘要:釋放不完全導致內存泄漏。既然把柔性數組放在動態內存管理一章,可見二者有必然的聯系。包含柔性數組的結構用進行動態內存分配,且分配的內存應大于結構大小,以滿足柔性數組的預期。使用含柔性數組的結構體,需配合以等動態內存分配函數。 ...
閱讀 1376·2021-10-14 09:43
閱讀 4209·2021-09-27 13:57
閱讀 4552·2021-09-22 15:54
閱讀 2547·2021-09-22 10:54
閱讀 2350·2021-09-22 10:02
閱讀 2108·2021-08-27 13:11
閱讀 867·2019-08-29 18:44
閱讀 1639·2019-08-29 15:20