c++内存机制
首先,来谈谈C++的5个存储区:
1.栈:是分配给函数局部变量的存储单元,函数结束后,该变量的存储单元自动释放,效率高,分配的空间有限。
2.堆:由new创建,由delete释放的动态内存单元。如果用户不释放该内存,程序结束时,系统会自动回收。
3.自由存储区:由malloc创建,由free释放的动态内存单元,与堆类似。
4.全局(静态)存储去:全局变量和静态变量占一块内存空间。
5.常量存储区:存储常量,内容不允许更改。
本文主要是来讨论栈和堆的区别,以及深入到C++汇编中来研究。先声明一下,以下的汇编都只是节选主程序的一块。
在linux下,编辑程序aaa.cpp,vim aaa.cpp
然后退出保存
输入命令
g++ -g -o aaa aaa.cpp
注意必须要参数-g,否则不会有汇编信息
接着输入反汇编命令
objdump -S aaa
得到底层的汇编实现
如果熟悉linux下的编程,会发现为什么那么多大牛喜欢linux,效率很快。在看程序之前,可能会由同学会注意到和windows下的有一些区别,linux下用的汇编类型是AT&T,而windows下是intel汇编,两者之间有些区别,但是C++的内存分配基本原理是一样的。
接下来,我们来仔细看看其内存分配。
首先为什么函数中声明的局部变量a,怎么没有对应的汇编语句,因为局部变量的声明只是规定了变量的类型和名字,并没由申请存储空间。
变量b在栈上分配一个字节的内存:在栈上分配了一块内存,初始化该变量的值。esp是栈顶指针。
变量c是先在栈上分配了一个指针大小的内存,这块内存是用来存储指针c的,再在堆空间上分配内存
变量p是在栈上分配了12*4个字节的大小,用来存储数组指针,再给这些变量对应分配堆内存空间。
这是内置数据类型的情况,如果分配的是类对象类型呢?
程序ccc.cpp如下:
对应的汇编程序:
还有类的内部成员函数的实现,现在就先不介绍了,看汇编真的是一件很累的事,但是真的是矫正来我之前很多的误解。不建议初学者来看,会迷失掉。
对于栈上分配类对象的情况,如语句 A a(10)
先在栈上分配对应大小的内存,然后再调用类的构造函数
在堆上分配类对象内存的情况,语句A* b=new A(12);
大致过程是,先在栈上分配一个指针大小的内存用来存储变量b,然后在堆上分配类大小的内存,再调用类的构造函数。
以上都是创建对象的过程,以下是释放内存的过程。
delete b;
大致过程是,先调用类的析构函数,再将对应的堆栈释放。下面是具体析构函数。