###### 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
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.