###### tags: `C/C++` `pointer` # C/C++: 動態記憶體配置 ## C-style動態記憶體配置 定義在<stdlib.h>標頭檔中。 ### malloc function 原型為: ``` void *malloc(size_t size); ``` 例如: ``` int *p1 = (int*) malloc(10*sizeof(int)); ``` (int*)為強制轉型為整數指標。 因為原本回傳值是void*。 ### free function ``` free(p1); ``` 一般來說,呼叫一次malloc()都要對應一次free(),否則會造成記憶體洩漏(memory leak)。 常用的方法為配置動態陣列: ``` int main() { int *dynArr; int arrLen = 10; dynArr = malloc(arrLen * sizeof(int)); if(dynArr == NULL){ printf("Error\n"); return 1; } int i; for(i=0; i<arrLen; ++i){ dynArr[i] = i; // 等同於 // *(dynArr+i) = i; printf("%d ", dynArr[i]); } free(dynArr); return 0; } ``` malloc()配置新記憶體後,會回傳該空間第一個byte的指標。 如果配置失敗,會回傳NULL。 ### calloc function 另一個calloc(),也是大同小異。 malloc()只配置空間但不初始空間的值。 calloc()會被自動初始化為0或NULL。 ``` void* calloc (size_t num, size_t size); ``` ## realloc function 改變已經分配過的空間。 如果失敗,回傳NULL。 ``` void *realloc(void *ptr, size_t size): ``` 如果size設為0,效果等同free()。 ``` realloc(ptr, 0); ``` 要注意的是,應避免: ``` ptr = realloc(ptr, new_size); ``` 因為如果失敗,會造成Memory leak。 應該寫成: ``` new_ptr = realloc(ptr, new_size); if(new_ptr == null){ // 錯誤處理 } ptr = new_ptr; ``` ## C++ style動態記憶體配置 ### new ``` int *p1 = new int; int *p2 = new int(7); if(p1 == NULL) // 錯誤處理 ``` ### Dynamic array 一維陣列: ``` int *p3 = new int[10]; ``` 二維陣列: ``` int (*p4)[10][20] = newdouble[5][10][20]; ``` 第一維可以是未知值的變數,但二維以上必須是已知。 也可以這樣分配: ``` int** m; m = new int*[3]; for(int i = 0; i<3; i++) { m[i] = new int[6]; } ``` ### delete ``` delete p1; delete [] p3; // 釋放陣列的記憶體配置空間 ``` delete是針對指標內所存的記憶體位址,而非指標。仍可對其再進行記憶體體配置。 ## References: [1] http://hackgrass.blogspot.com/2018/03/c-pointerint-foo-int-bar.html [2] https://blog.gtwang.org/programming/c-memory-functions-malloc-free/ [3] http://hungming.ct.ntust.edu.tw/2019spring/ct3407/classnotes/ct3407_13.pdf [4] https://ithelp.ithome.com.tw/articles/10204463 [5] https://xyz.cinc.biz/2013/09/c-pointer-dynamic-memory.html