c++-面试题_堆和栈的区别

C++的内存分配可以分为3种,静态内存、栈内存、堆内存。
一、静态内存:存储静态变量和全局变量
1、静态变量(包括局部静态变量、类的静态数据成员、全局静态变量)在静态内存中分配内存,当整个程序运行完毕之后才销毁变量,释放内存。
2、初始化时间:
局部静态变量:就是定义在函数或者语句块中的局部静态变量,在第一次使用之前分配内存。
非局部静态变量:在main函数之前的静态初始化过程中分配内存。
3、类静态变量初始化方式
1)静态成员函数(与非静态成员函数一样)既可以在类内初始化也可以在类外初始化。因为静态成员不属于任何一个类,所以不包含this指针,所以静态成员函数中不能使用this指针,也不能使用类的非静态数据成员,即只能使用静态数据成员。
2)静态数据成员在类内声名,类外定义。
3)常量静态数据成员可以在类内定义。如:static constexpr int num=30;

二、说一说栈和堆的区别
1、内存分配方式不同
1)栈内存:
存储局部变量、临时变量、函数参数等,由编译器自动分配和回收内存,

2)堆内存:
由程序员手动分配和回收内存,使用new运算符手动申请内存,必须使用delete手动释放内存

2、申请大小限制

栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存区域。栈通常是有大小限制的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于操作系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

3.申请后系统的响应

栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:在记录空闲内存地址的链表中寻找一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。另外,对于大多数系统会在这块内存空间的首地址出记录本次分配空间的大小,这样代码中的delete才能正确释放本内存空间。系统会将多余的那部分重新空闲链表中。

4、分配效率不同
栈的效率比较高,栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比 较高。
堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆 内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分 到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。

参考
栈内存和堆内存的区别(一个笔试题的一部分)

C++内存管理学习堆和栈

你可能感兴趣的:(面试)