動態內存分配
c之malloc
函數原型:
void* malloc(size_t size);
- 爲用戶申請size個字節大小的空間
- 成功返回地址,失敗返回0
常見使用方式:
//第一種是錯誤的,原因是返回爲void*,缺少指針的二元素之一:類型,所以編譯器不認識
int* a = malloc(sizeof(int));
//以下幾種都正確
int* a = (int*)malloc(sizeof(int));
int* a = (int*)malloc(4); //int佔4個字節
int* a = (int*)malloc(sizeof(int)*10); //分配10個int空間
c之calloc
函數原型:
void* calloc(size_t count, size_t size);
- 爲用戶申請count*size個字節大小的空間
- 成功返回地址,失敗返回0
- 分配成功後,每個區域值設置爲0
常見使用方式:
int* a = (int*)calloc(sizeof(int),3);
c之realloc
函數原型:
void* realloc(void* _Block, size_t Size);
- 爲已分配好的內存_Block重新分配Size個字節大小的內存
- 成功返回地址重分配後的首地址,失敗返回0
常見使用之例程講解:
int* pa = (int*)calloc(sizeof(int), 10);
pa[0] = 1; pa[1] = 2; pa[2] = 3;
int* pb = (int*)realloc(pa, 20);
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
結果:
總結: 我們發現確實是重分配,並且數據也已經正確,但是在這裏我們需要注意的是重分配有可能是擴大也有可能是縮小;大了可能會溢出,小了可能會數據丟失。
擴充: 若縮小內存,則新分配內存首地址就是原首地址。若擴大至一定內存,則極有可能由於後部代碼塊不夠用,而重新在另一處開闢一塊需要的內存大小,並且將原數據拷貝紙新內存,這樣新內存的首地址就發生變化了
c之free
函數原型:
void free(void* _Block);
- 僅釋放_Block動態分配的內存
常用形式:
int* a = (int*)malloc(sizeof(int));
free(a);
總結:雖然釋放了內存,但以上代碼會造成懸掛指針的問題,如下:
int* a = (int*)malloc(sizeof(int));
free(a);
cout << a;
結果:
總結: 依然能打印地址,所以還需要將a = nullptr (c++11標準以及標準之後)
c++之new
使用形式:
1、數據類型 * 指針變量名 = new 數據類型;
例如:
int * pa = new int;
2、數據類型 * 指針變量名 = new 數據類型[數量];
例如:
int * pa = new int[5];
- 失敗返回0
常用形式:
int* pa = new int{ 1 };
cout << *pa << endl;
int* pb = new int[3]{1,2,3};
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
結果:
總結: 分配時就可進行初始化值
c++之delete
使用形式:
1、delete 指針; //釋放類似於int * pa = new int;開闢的內存
2、delete [] 指針;//釋放類似於int * pa = new int[5];開闢的內存
示例:
//必須配套使用
int* pa = new int{ 1 };
delete pa; //一個就這個
int* pb = new int[3]{1,2,3};
delete [] pb; //多個就這個
內存拷貝常用之memcpy
函數原型:
void* memcpy(void* _Dst, void* _Src, size_t Size);
- _Dst爲目的地址
- _Src爲原地址
- Size 拷貝字節數
- 將以_Src首地址開始的Size個字節拷貝到首地址爲_Dst的內存區域
範例代碼:
int* pa = new int[3]{ 1,2,3 };
int* pb = new int[3];
memcpy(pb, pa, sizeof(int)*3);
cout << pb[0] << " " << pb[1] << " " << pb[2] << endl;
結果:
內存拷貝常用之memset
函數原型:
void* memset(void* _Dst, int val, size_t Size);
- 設置以首地址爲_Dst開始的Size個字節內設置爲val
- val最好是小於一個字節,否則截斷一個字節的內容
範例代碼:
int* pa = new int[3]{};
memset(pa, 0, sizeof(int) * 3); //這種基本上是最常用的
cout << pa[0] << " " << pa[1] << " " << pa[2] << endl;
//演示value高於一個字節用
memset(pa, 0xff32, sizeof(int) * 3); //純屬是演示用,平時不會這麼用
cout << hex; //設置爲16進制輸出流
cout << pa[0] << " " << pa[1] << " " << pa[2] << endl;
結果:
感謝自己努力的學習!!認爲還不錯的大哥們記得點個贊哦!謝謝0.0