堆、栈与内存管理

时间:2021-09-08 19:49:01

 

首先,我们来看一下之前在写complex类时写过的

class Complex{....};
.....
{
Complex c1(
1, 2);
Complex
* p = new Complex(3);
........
delete p;}

上面使用了两种对象的创建方式,其中c1是直接创建的,占用的空间来自stack,

Stack,是存在于某个作用域(scope)的一块内存空间,例如,当调用函数,函数本身即会形成一个stack用来放置它所接受的参数,以及返回地址。在function body内声明的任何变量,所使用的内存都是取自stack。stack object 的生命在离开作用域就结束了,又叫local object,会自动调用其析构函数,清理。

另外一种内存的来源就是堆(heap),是指由操作系统提供的一块全局内存空间,使用new取得这一块内存空间,程序可动态分配从某种获得若干区块(block)

 Complex(3); 创建一个初值是3内存来自heap的对象,与上面创建对象的差别是,可在程序的任何地方,以new的方式动态获得这一块,需要自己手动delete.

还要一种static object,例如 static Complex c2(2,1);就是所谓的static object,其生命在作用域结束后仍然存在,直到程序结束,

还有一种全局对象,写在任何作用域之外,在mian()之前就存在了,在main()结束后才消失,存在和消失对应其构造函数和析构函数的调用时刻。

下面图片可以形象的说明new的使用(图片来源于侯捷老师的课件)

 

 堆、栈与内存管理     堆、栈与内存管理

 

new这个动作被编译器分解为上面图片中的三个动作,相当于调用malloc(),1.分配内存;2.转型;3.调用构造函数

与new对应的是delete,编译器解释为两个动作,1.调用析构函数,2.释放内存

 动态分配所得的内存块(in VC)(来源于侯捷老师的课件)

堆、栈与内存管理

比如, Complex* pc = new Complex(1,2) 会占用8个字节,但是在调试模式下,会占用图一所示的空间,上面灰色每一格是4byte。非调试模式下,占用内存空间是第二张图,占用16个:复数两个double,8个字节,上下两个cookie,8个字节,共16。