c++内存机制

首先,来谈谈C++的5个存储区:

1.栈:是分配给函数局部变量的存储单元,函数结束后,该变量的存储单元自动释放,效率高,分配的空间有限。

2.堆:由new创建,由delete释放的动态内存单元。如果用户不释放该内存,程序结束时,系统会自动回收。

3.自由存储区:由malloc创建,由free释放的动态内存单元,与堆类似。

4.全局(静态)存储去:全局变量和静态变量占一块内存空间。

5.常量存储区:存储常量,内容不允许更改。

本文主要是来讨论栈和堆的区别,以及深入到C++汇编中来研究。先声明一下,以下的汇编都只是节选主程序的一块。

在linux下,编辑程序aaa.cpp,vim aaa.cpp

c++内存机制

然后退出保存

输入命令  

  g++ -g -o aaa aaa.cpp

注意必须要参数-g,否则不会有汇编信息

接着输入反汇编命令

objdump -S aaa

得到底层的汇编实现

c++内存机制

如果熟悉linux下的编程,会发现为什么那么多大牛喜欢linux,效率很快。在看程序之前,可能会由同学会注意到和windows下的有一些区别,linux下用的汇编类型是AT&T,而windows下是intel汇编,两者之间有些区别,但是C++的内存分配基本原理是一样的。

接下来,我们来仔细看看其内存分配。

首先为什么函数中声明的局部变量a,怎么没有对应的汇编语句,因为局部变量的声明只是规定了变量的类型和名字,并没由申请存储空间。

变量b在栈上分配一个字节的内存:在栈上分配了一块内存,初始化该变量的值。esp是栈顶指针。

变量c是先在栈上分配了一个指针大小的内存,这块内存是用来存储指针c的,再在堆空间上分配内存

变量p是在栈上分配了12*4个字节的大小,用来存储数组指针,再给这些变量对应分配堆内存空间


这是内置数据类型的情况,如果分配的是类对象类型呢?

程序ccc.cpp如下:

c++内存机制

对应的汇编程序:

c++内存机制

还有类的内部成员函数的实现,现在就先不介绍了,看汇编真的是一件很累的事,但是真的是矫正来我之前很多的误解。不建议初学者来看,会迷失掉。

对于栈上分配类对象的情况,如语句 A a(10)

先在栈上分配对应大小的内存,然后再调用类的构造函数

c++内存机制

在堆上分配类对象内存的情况,语句A* b=new A(12);

大致过程是,先在栈上分配一个指针大小的内存用来存储变量b,然后在堆上分配类大小的内存,再调用类的构造函数

以上都是创建对象的过程,以下是释放内存的过程。

delete b;

大致过程是,先调用类的析构函数,再将对应的堆栈释放。下面是具体析构函数。

c++内存机制