【C++學習筆記】----內存管理(new、delete、malloc、free、內存分佈圖、各數據所在區域。)

1.常見面試題

1.new和malloc,delete和free的區別?

new和delete,malloc和free
首先new 和 delete是關鍵字(操作符),而malloc和free是函數。
new會初始化對象,malloc不會。
new根據所需對象的個數,直接開闢空間;malloc需要自己計算字節大小開闢。
new不需要,malloc返回值需要強轉成需要的類型。
new開闢失敗會拋異常,而malloc會返回NULL。
針對自定義類型new會調用構造函數,delete會調用析構函數,malloc和free不會。

new底層調用operator new函數,operator new底層是Malloc實現,但是多了一個拋異常。(delete類似)

2.malloc,calloc,realloc區別?

malloc按字節開闢大小,不初始化。
calloc和malloc差不多,但是會初始化爲0。
realloc擴容,擴容失敗返回NULL,擴容成功原來空間自動釋放。
在這裏插入圖片描述
3.如何在堆上申請4G內存?

32位地址空間下不能申請大於0x7fffffff的空間,所以要在64位空間下申請。

4.定位New.
malloc開闢一段空間,未初始化,定位new調用構造,初始化數據成員。
在這裏插入圖片描述

2.內存分佈

在這裏插入圖片描述

3.代碼展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
static int val1 = 1;//.data 數據段	
int val2 = 2;//.data
void test1()
{
	
	static int val3 = 3;//數據段
	int val4 = 4;//棧
	int arr1[10] = { 97,2,3,4 };//棧-數組
	char arr2[] = { 'a','b','c','d','e' };//棧-數組
	char arr3[] = "abcde";//棧-數組
	const char* arr4 = "abcde";//代碼段不可以改(確認)
	int* arr5 = (int*)malloc(sizeof(int) * 4);//堆
	int* arr6 = (int*)realloc(arr5, sizeof(int) * 5);//堆
	//cout << "數據段val1->" << &val1 << endl;
	//cout << "數據段val2->" << &val2 << endl;
	//cout << "數據段val3->" << &val3 << endl;
	//cout << "棧val4->" << &val4 << endl;
	//cout << sizeof(val1) << endl;
	//cout << sizeof(val2) << endl;
	//cout << sizeof(val3) << endl;
	//cout << sizeof(val4) << endl;
	//printf("%p\n", arr1);//指向第一個元素
	//printf("%p\n", &arr1+1);//跳過整個數組大小
	//printf("%c\n",*(arr2+1)-32);//B
	//printf("%p\n", arr2);//棧
	//printf("%p\n", arr3);//棧
	//printf("%s\n", arr2);//無\0,燙燙燙
	//printf("%s\n", arr3);//有\0
	//printf("%p\n", &arr3+1);//跳過整個數組大小
	//printf("%s", arr1);
	//printf("%c", *arr1);
	//字符串輸出的話,遇到0結束,所以內存中讀取時,char讀取所以內存中97對應的是a,
	//由於我們數組本來是int類型,所以高位0存在高位,整型截斷,直接輸出。
	//printf("%p\n", arr4);
	//printf("%s\n", arr4);
	//printf("%p\n", &arr5);//指針的地址在棧
	//printf("%p\n", &arr5+1);//指針的地址在棧+1-》+4
	//printf("%p\n", arr5);//指針指向的空間在堆
	//printf("%p\n", arr5+1);//指針指向的空間在堆
	//printf("%p\n", &arr6);//指針的地址在棧
	//printf("%p\n", arr6);//指針指向的空間在堆



	//cout << sizeof(arr1) << endl;//40
	//cout << sizeof(arr2) << endl;//5數組
	//cout << sizeof(arr3) << endl;//6數組
	//cout << sizeof(arr4) << endl;//4指針
	//cout << sizeof(arr5) << endl;//4指針
	//cout << sizeof(arr6) << endl;//4指針


	//cout << strlen(arr2) << endl;//不確定,取決於後面空間0的位置
	//cout << strlen(arr3) << endl;//5
	//cout << strlen(arr4) << endl;//5
}
class A
{
public:
	A()
	{
		cout << "A()" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
};
void test2()
{
	/*int* arr1 = (int*)malloc(sizeof(int) * 10);
	free(arr1);
	int* arr2 = new int[10];
	delete arr2;*/

	A* a1 = (A*)malloc(sizeof(A) * 10);
	free(a1);
	A* a2 = new A[10];//自定義類型調用構造和析構
	delete[] a2;

}
void test3()
{
	void* p = new char[0xffffffff];//64位下
	cout << "new:" << p << endl;


}
void test4()
{
	int* arr1 = (int*)malloc(sizeof(int) * 10);
	int* arr2 = (int*)calloc(10, sizeof(int));
	int* arr3 = (int*)realloc(arr1,0x6fffffff);
	cout << arr1 << endl;
	cout << arr2 << endl;
	cout << arr3 << endl;
	cout << arr1 << endl;
}
void test5()
{
	A* a1 = (A*)malloc(sizeof(A) * 10);
	new(a1) A;
	delete A;
}
int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	system("pause");
	return 0;
}

4.總結分析

(1).sizeof字節大小,32位下指針都是4字節,如果是數組名,計算的是整個數組大小。
在這裏插入圖片描述
(2).“abc”=3,後面有隱含的\0。所以char arr4 []=“abc” sizeof(arr4)=4,strlen是以\0爲標誌結束,所以長度是3,後面會有一個\0;{a,b,c}沒有,strlen就不能計算它的長度了。

(3).全局變量,靜態變量在數據區,臨時變量局部變量在棧區,動態開闢的區域在堆區(*arr),(arr)即(&arr)在棧區,不可以改常量、函數在代碼段。

(4).val1、val2,全局變量。初始化在main函數之前,val2(全局)所有文件可見,val1(靜態全局)當前文件可見,鏈接屬性不同。
而val3靜態局部變量只能在當前作用域使用,運行到它才初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章