###### 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