C語言之動態記憶體管理
關於動態記憶體管理
關於動態記憶體管理的函式原型定義在stdlib.h
標頭檔案中,Linux系統中該標頭檔案所在路徑為:/usr/include/
,stdlib.h
中定義的與動態記憶體管理相關函式的原型為:
void *malloc(size_t size);
void *calloc(size_t numElement, size_t elementSize);
void *realloc(void *ptr, size_t size);
void free(void *ptr);
從堆中分配記憶體
void *malloc(size_t size)
malloc
函式通過引數指定需要分配的記憶體大小(單位:位元組),若堆中存在足夠記憶體則返回起始地址,否則返回NULL
,示例程式碼如下:#include <stdlib.h> #include <stdio.h> int main(void) { int *ptr = (int *) malloc(5 * sizeof(int)); if (!ptr) { printf("out of memory\n"); return -1; } /***** do something for ptr here *****/ free(ptr); // 手動釋放動態分配的記憶體 ptr = NULL; // 堆記憶體釋放後,指標一般置為空指標,否則會造成懸空指標 return 0; }
從堆中開闢的記憶體使用完畢必須手動釋放歸還給堆管理器
void *calloc(size_t numElement, size_t elementSize)
calloc
函式通過指定元素個數和元素大小分配記憶體,若堆中存在足夠記憶體則返回起始地址,否則返回NULL
,示例程式碼如下:#include <stdlib.h> #include <stdio.h> int main(void) { int *ptr = (int *) calloc(5, sizeof(int)); if (!ptr) { printf("out of memory\n"); return -1; } /***** do something for ptr here *****/ free(ptr); ptr = NULL; return 0; }
但和
malloc
不同的是calloc
會對開闢的記憶體進行零初始化,即int *ptr = (int *) calloc(5, sizeof(int));
與下述程式碼等價(memset函式原型定義在string.h中):int *ptr = (int *) malloc(5 * sizeof(int)); if (ptr) { memset(ptr, 0, 5 * sizeof(int)); }
void *realloc(void *ptr, size_t size)
realloc
函式作用為擴大或縮小已分配的堆記憶體或者NULL
,該函式接受兩個引數,第一個引數指定要擴大或縮小的記憶體地址;第二個引數指定擴大或縮小後的記憶體大小,示例程式碼如下:#include <stdio.h> #include <stdlib.h> int main(void) { int *ptr = (int *) malloc(5 * sizeof(int)); if (!ptr) { printf("out of memory\n"); return -1; } int *tmp_ptr = (int *) realloc(ptr, 10 * sizeof(int)); if (!tmp_ptr) { printf("out of memory\n"); free(ptr); // 若不再需要ptr則需釋放 ptr = NULL; return -1; } ptr = tmp_ptr; tmp_ptr = NULL; // 一般保證開闢的堆記憶體只有一個引用,否則容易重複釋放 /***** do something for ptr here *****/ free(ptr); ptr = NULL; return 0; }
使用
realloc
需要注意的是當記憶體不足返回為NULL
時,realloc
不會將引數ptr
指向的記憶體釋放,需要人為動手釋放,因此不可以寫如下程式碼:#include <stdlib.h> int main(void) { int *ptr = (int *) malloc(5 * sizeof(int)); if (!ptr) { printf("out of memory\n"); return -1; } ptr = (int *) realloc(ptr, 10 * sizeof(int)); /*****此處若記憶體不足realloc返回NULL,ptr將丟失之前malloc分配的記憶體地址,造成記憶體洩漏*****/ return 0; }
釋放記憶體
void free(void *ptr)
free
函式的作用是將從堆中分配的記憶體釋放歸還給堆,以便後續可以分配給其他的物件,該函式的引數為動態分配記憶體的地址。使用free
函式時要注意,引數必須為malloc
、calloc
、realloc
的返回值或NULL
,否則將產生free(): invalid pointer
執行時錯誤,示例程式碼1如下:#include <stdio.h> #include <stdlib.h> int main(void) { int a = 99; int *ptr = &a; free(ptr); // 產生執行時錯誤,因為ptr指向棧記憶體 ptr = NULL; return 0; }
示例程式碼2如下:
int main(void) { int *ptr = (int *) malloc(5 * sizeof(int)); ptr++; free(ptr); // 產生執行時錯誤,因為ptr已經不指向malloc分配記憶體的首地址 ptr = NULL; return 0; }
相關文章
- C++動態記憶體管理——new/deleteC++記憶體delete
- C++動態記憶體管理與原始碼剖析C++記憶體原始碼
- c++動態記憶體管理與智慧指標C++記憶體指標
- C和C++的動態記憶體管理的區別C++記憶體
- C++動態記憶體分配C++記憶體
- 學了指標沒學動態記憶體一切都白搭!C語言基礎教程之記憶體管理指標記憶體C語言
- C++ 指標動態記憶體分配C++指標記憶體
- C語言之結構體C語言結構體
- C++記憶體管理C++記憶體
- C語言-記憶體分配C語言記憶體
- 動態記憶體分配記憶體
- C++記憶體管理剖析C++記憶體
- Objective-C記憶體管理Object記憶體
- Objective-C 記憶體管理Object記憶體
- c語言野指標與結構體指標動態記憶體分配小解C語言指標結構體記憶體
- 【記憶體管理】Oracle AMM自動記憶體管理詳解記憶體Oracle
- C語言記憶體對齊C語言記憶體
- C語言的記憶體分配C語言記憶體
- 【記憶體管理】Oracle如何使用ASMM自動共享記憶體管理記憶體OracleASM
- 記憶體管理 記憶體管理概述記憶體
- Rust語言記憶體管理之妙Rust記憶體
- Objective-C記憶體管理:BlockObject記憶體BloC
- Objective-C記憶體管理:物件Object記憶體物件
- 【C/C++】4.C++的記憶體管理C++記憶體
- C++ 動態記憶體分配與名稱空間C++記憶體
- C++記憶體管理:簡易記憶體池的實現C++記憶體
- golang手動管理記憶體Golang記憶體
- C語言記憶體管理,分配、使用、釋放以及安全性C語言記憶體
- C語言細節 儲存類別,連結,記憶體管理C語言記憶體
- 記憶體管理篇——實體記憶體的管理記憶體
- 【記憶體管理】記憶體佈局記憶體
- C++記憶體管理:new / delete 和 cookieC++記憶體deleteCookie
- 記憶體管理兩部曲之實體記憶體管理記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- JVM學習-自動記憶體管理JVM記憶體
- C語言之基本概念C語言
- C語言之氣泡排序C語言排序