一、所谓stack和heap 例子:
class complex{...}; .... //作用域(scope) { complex c1(1,2);//从c1在作用域中相当于int a=0;的局部变量,存在于作用域中的一块内存,当调用函数是就会形成stack来方式参数以及返回地址,但是在函数结束的时候,这个对象就会消失。 complex * p = new complex(3);//这是通过new动态分配的内存,是通过操作系统提供的一块global内存空间,程序通过new动态分配独得若干区块,保存在heap中。 }stack:保存局部变量或临时对象的一块内存,函数调用结束会消失 heap:存放全局对象或变量的内存空间,函数调用结束如果不通过delete[] 释放将直到程序运行结束之前一直存在。 二、static local objects 为了让将函数中的局部变量或临时对象一直存在直到程序结束为止,那么既可以用静态声明来实现。
三、global objects 声明在整个程序结束之后才结束。 四、heap objects生命期 complex * p = new complex(3); 。。。 delete p;//p所指的便是heap object,其生命在他被deleted之际结束。 当不用delete时,会出现内存泄露,因为指针指向的内存空间任然存在。 补充:new:先分配memory,再调用actor(分配内存用过malloc()实现,释放用free())
五、内存管理(动态分配所得到的的array)
//动态分配一个复数 Complex* pc = new Complex(1,2);//new一个复数会获得的大小为8byte(复数,两个double(每个double 4bytes)),但是在调试模式下不止8byte。 动态分配所得的内存块(memory block),in VC 8+(32+4)+(4*2) = 52//52不能整除16,所以分配64bytes内存
也就是在new分配内存时,会多分配多得多的内存,这是必要的,因为在回收的时候能用到。 分配的空间中,头地址会表示内存,是16的倍数,最后一个byte1表示用户收回,0表示用户给出。例如:00000041表述64bbytes空间加上1表示用户收回,一共65bytes.
Q:如果分配的是数组呢? A: Complex* p = new Complex[3]; 三个复数:83 = 24byte 调试模式下:24+(32+4)+(42) +4 = 72//分配80byte(50h+1 = 51h),调到16的边界 非调试模式下:(38)+(42) = 36;//分配48
String* p = new String[3]; 同理。 注意:array new一定要搭配 array delete 例如:Complex* p = new Complex[3]; delete [] p;//也就是加[],如果不加可能出现内存泄漏。[]是告诉编译器要删除的是一个数组,而不是一个数组中的首元素中的内存中的数据,其他的并没有回收,从而会出现内存泄露。