栈Stack
存在于某作用域的一块内存空间,假如调用一个函数,该函数本身会形成一个stack用来放置它所接收的参数,以及返回的地址。
在函数本体中声明的任何变量,其所使用的内存块均取自上述stack
堆Heap
又称system heap,是由操作系统分配提供的一块global内存空间,程序可动态分配从中取得若干区块(用new)
stack objects
c1(stack objects)生命在其作用域结束时结束,这种作用域内的object又称auto object,因为他会被自动清理(自动调用析构函数)。而p所指的是堆中的对象。
static local objects
下图的c2(static object)其生命在作用域结束之后仍然存在,直到程序结束
global objects
c3(globa object)生命在整个程序结束之后才会结束,也可以当做一种static object,作用域是整个程序
heap objects
p所指的就是heap object需要手动delete销毁,生命在delete时才结束
这样会出现内存泄漏 ,因为当作用域结束时,指针p的生命就结束了,但是它所指向的heap object仍然存在,而我们也无法delete p了
new的全过程:
先分配内存再调用构造函数
delete的全过程:
先调用析构函数再释放内存,若先释放内存,就无法找到对应的对象执行析构函数释放该对象中new占用的堆内存
内存管理
第一列:调试模式下Complex的内存分配
头尾是cookie,表示这块内存占用了多大,64转换成16进制是40
借用最后一位,1表示分配内存,0表示释放内存
Complex中两个double8个字节,上面的32字节,下面的4字节,加上cookie总共52个字节,但是要求是16的倍数,所以用pad填充到64字节。
正是因为是16的倍数,最后四位都是0,所以可以借用后面四位用来做别的事,例如cookie的最后一位表示分配或释放
第二列:release模式下的Complex内存分配
加上cookie16个字节
第三列:调试模式下String内存分配
string中只有一个指针,4个字节。其他同理计算。
第四列同理
不同编译器分配的内存不同
动态分配数组
vc中用一个整数来表示数组大小,不同编译器不一样
array new一定要搭配array delete,否则会造成内存泄漏,泄露的是后续未执行析构函数的对象new的对象