【C++】内存数据分布知识,malloc和new的区别(面试常问),干货满满~


在这里插入图片描述

前言

学习完C++类和对象之后,做了一些C++内存数据分布的题目,感觉很有用,干货满满,遂分享给大家学习。

1.各种类型的内存数据分布

int globalVar = 1;

static int staticGlobalVar = 1;

void Test()
{

	static int staticVar = 1;
	
	int localVar = 1;

	int num1[10] = {1, 2, 3, 4};

	char char2[] = "abcd";

	char* pChar3 = "abcd";

	int* ptr1 = (int*)malloc(sizeof (int)*4);

	int* ptr2 = (int*)calloc(4, sizeof(int));

	int* ptr3 = (int*)realloc(ptr2, sizeof(int)*4);

	free (ptr1);

	free (ptr3);
}
  1. 选择题:

选项: A.栈 B.堆 C.数据段(静态区) D.代码段(常量区)

1.globalVar在哪里?____ 2.staticGlobalVar在哪里?____

3.staticVar在哪里?____ 4.localVar在哪里?____

5.num1 在哪里?____

6.char2在哪里?____ 7.*char2在哪里?___

8.pChar3在哪里?____ 9.*pChar3在哪里?____

10.ptr1在哪里?____ 11.*ptr1在哪里?____

  1. 填空题:

sizeof(num1) = ____;

sizeof(char2) = ____; strlen(char2) = ____;

sizeof(pChar3) = ____; strlen(pChar3) = ____;

sizeof(ptr1) = ____;

1.1解析

选择题:
1.globalVar全局变量存放在在数据段。 2.staticGlobalVar静态全局变量在静态区
3.staticVar静态局部变量也是在静态区 4.localVar局部变量在栈区
5.num1是数组,本质是局部变量在栈区
6/7.char2是一个数组,把后面常量串拷贝过来到数组中,数组在栈上,故char2,*char2都在栈上
8. pChar3局部变量在栈区 9. *pChar3是字符串常量字符在代码段
10/11.ptr1局部变量在栈区 *ptr1得到的是动态申请空间的数据在堆区

填空题:
sizeof(num1) = 40;//数组大小,10个整形数据一共40字节
sizeof(char2) = 5;//包括\0的空间
strlen(char2) = 4;//不包括\0的长度
sizeof(pChar3) = 4/8;//pChar3为指针,32位下为4,64位下为8
strlen(pChar3) = 4;//字符串“abcd”的长度,不包括\0的长度
sizeof(ptr1) = 4/8;//ptr1是指针,32位下为4,64位下为8

1.2总结

在C++中,数据会存放到这四个地方:栈、堆、数据段(静态区)、代码段(常量区)
其中全局变量存放在数据段局部变量存放在栈,带静态变量不管是局部还是全局都存放在数据段(静态区),常量存放在代码段(常量区)动态申请空间(malloc、new)的数据在堆区
                在这里插入图片描述

2.c++内存分配堆栈问题

下面有关c++内存分配堆栈说法错误的是( )

A.对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制。
B. 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长。
C.对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题。
D.一般来讲在 32 位系统下,堆内存可以达到4G的空间,但是对于栈来讲,一般都是有一定的空间大小的。

2.1解析

答案:D
A:栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需要时需要手动释放。

B:栈遵循后进先出,栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反(我看到有一个说法:堆和栈的生长方向并不是普遍固定的,具体取决于系统架构,求高手解答正确与否)
                     在这里插入图片描述

C:栈的内存空间频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,并且栈是顺序分配和释放的,不会出现碎片化。

D:32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用,故错误
在这里插入图片描述

3.堆和栈是否都能进行动态/静态分配?

3.1解析

堆和栈都可以静态分配
这句话是错误的

堆:堆内存的分配是动态的,通过 new 或 malloc 等函数在运行时分配和释放内存。
栈:栈内存的分配是静态的,编译时确定栈的大小,内存分配和释放由编译器和运行时系统自动管理。

堆和栈都可以动态分配
这句话是部分正确但有点误导。

堆:支持动态分配内存。
栈:栈的分配是在编译时确定的,虽然栈的内存使用是动态的(比如函数调用时栈帧的分配),但栈的总大小是静态分配的,不是动态的。

4.函数参数与malloc和new使用的空间在哪申请

函数参数使用的空间是在:栈 中申请的。

当函数被调用时,参数会作为函数调用的一部分存储在栈帧中,函数的局部变量和参数通常都是在栈上分配的。

malloc 或 new 是在:堆 中申请空间的。

malloc 和 new
用于动态分配内存,它们在堆中分配内存,这块内存的生命周期不受函数的作用域限制,直到手动调用 free(对于 malloc)或delete(对于 new)来释放内存。

5.关于malloc和new的知识

new和malloc,都是我们动态申请空间所使用的,它们两个的最大区别就是是否会自动调用构造函数。
new是操作符,而malloc是函数

new本质上就是malloc,为什么这么说呢?
在这里插入图片描述

new的原理是调用operator new函数申请空间,而operator new实际也是通过malloc来申请空间。
在这里插入图片描述
而且new申请空间如果失败了,会主动抛出异常,告诉我们多少字节空间出现问题,malloc则会返回NULL,如果用malloc我们还要对返回值进行判空,烦OvO。在这里插入图片描述

5.1总结:malloc和new的区别(面试常问)

malloc和new的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:

1.malloc是函数,new是操作符

2.malloc申请的空间不会初始化,new可以初始化

3.malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可

4.malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

5.malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需 要捕获异常

6.申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new 在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成 空间中资源的清理

本文到此结束~,有不对的地方请大声告诉我改正!
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值