堆、栈与内存管理
首先,我们来看一下之前在写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。