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靜態局部變量只能在當前作用域使用,運行到它才初始化。