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静态局部变量只能在当前作用域使用,运行到它才初始化。