文章目录
- 前言
- 一、内存分布
- 二、new 、delete 分配问题
- 总结
前言
本篇文章笔者将会对 C++ 中的内存问题简单的讲解 , 同时对 new , delete 的面试题进行重点讲解.
一、内存分布
● C语言和C++ 分布情况是一样的, 如下 :
● 栈
○ 栈 的管理是由编译器自动管理 , 不需要我们人为做什么操作.
○ 向下增长
同时压栈时也是向下增长.
○ 特别补充
栈是可以动态分配的 , 栈的动态分配是通过 _alloca进行动态分配 ,但是所分配空间不能通过free或delete进行释放
● 堆
○ 堆 的管理需要我们手动管理了 , 动态申请 和 释放需要程序员手动完成.
○ 堆只能动态分配内存
○ 向上增长
○ 特别补充
堆的大小受限于操作系统 , 一般 32 位系统分配给内存的空间是 4G , 而 64 位更大为 8G , 但是堆不可能全占用 .
二、new 、delete 分配问题
new 在 可以申请空间的同时进行初始化构造 , delete 在释放空间时可以进行析构(先析构清理资源 ,在释放).
在用 new , delete 时必须合理使用 , 要配套使用.
○ new - 配 - delete
○ new[] - 配 - delete[]
● 面试题
将给出以下代码 , 请解释一下为什么会有不同的现象 ? (代码在 vs2022 运行)
代码:
class A
{
public:A(int aa1 = 0, int aa2 = 0):_a1(aa1), _a2(aa2){cout << "A(int a1 = 0, int a2 = 0)" << endl;}~A(){cout << "~A()" << endl;}private:int _a1 = 1;int _a2 = 1;
};class B
{
public:B(int aa1 = 0 , int aa2 = 0):_a1(aa1), _a2(aa2){cout << "B(int aa1 = 0 , int aa2 = 0)" << endl;}private:int _a1 = 2;int _a2 = 2;
};// 面试题
int main()
{//这个是没问题的B* pb = new B[10];delete pb;//这个程序就会崩溃A* pa = new A[10];delete pa;return 0;
}
以上代码出现两种不同的情况 , 一个正常运行 , 一个崩溃.
● 剖析
- 首先 , 给出的代码本身反映了一个问题 , 不匹配使用导致的不同结果
- 其次 , 具体观察可知 , A 中我们首先实现了析构函数 , B 中我们没有手动实现析构函数
那么关于这样的代码 ,我们只能 通过反汇编看看底层是怎么回事了 .
补充 : new[] - > 底层会调用 operator[] 函数 , 具体我们通过反汇编可知.
○ 反汇编观察
- 观察 B
- 观察 A
通过以上观察可看到 , 两个 new 出来的大小竟然不一样 , 到底什么原因呢 ?
○ 具体分析
● 总结
○ 对于内置类型的不匹配使用 new , delete 问题 , 这种问题是不大的 , 几乎没问题, 但是不推荐.
○ 对于自定义类型 , 实现了析构, 但又不匹配使用 new , delete 就会出大问题
○ 对于自定义类型 , 没有实现析构, 但又不匹配使用 new , delete 是没有什么问题 , 但不推荐使用.
○ 故: 在使用是一定要匹配使用 ,这样就不会有问题的产生.
总结
以上就是本篇的内容 , 希望读者认真领会.