c++之動態內存分配篇

動態內存分配

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

發佈了20 篇原創文章 · 獲贊 19 · 訪問量 2348
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章