文章目录
前言
栈与堆的区别,内存动态分配在调试模式、编译模式的变化。static的生命周期
一、栈、堆
栈(Stack)
栈是存在于某作用域(scope)内的一块内存空间(memory space),当你调用某函数,函数本身会形成一个stack用来放置它所接收的参数
堆(Heap)
堆是由操作系统提供的一块global内存空间。程序可以动态分配到其间赋若干区块(blocks)
二、static生命期
static也就是静态变量,可以在后面加上数据或者函数,他的生命周期是等待程序结束时候才会被自动清理。static函数调用可以直接通过类名调用,也可以创建一个类对象来调用。
三、heap生命期
通常搭配new和delete使用,由程序员自己创建和释放,如果忘记delete了,会有内存泄漏的风险,因为当作用域结束时候,p指针所指的内存还存在,但是此时指针p却结束了,所以就会导致内存泄漏
四、new、delete的作用机制
new的实际如图,可以概括为先分配内存,然后调用构造函数(转型只是把类型转换了),注意operator new底层是c中的malloc分配内存。构造函数会有赋值。
delete相反,先调用析构函数,然后释放内存空间(内部调用C的free)
五、动态分配的内存(in VC)
如图,第一列为调试模式下的复数的内存分配,复数有两个double,占用8个字节,灰色有上面8块加下面一块,所以是32+4。红色叫cookie,类似夹心饼干,故4*2。由于内存分配都是16的倍数,所以52要补到64,多出来的绿色就是补的。第二列是编译模式。第三列是string类的调试模式,string类只有一个指针占4个字节。
下图是数组的new,复制三遍所以8*3。最后多出来的4是因为数组会有一个标志位3。注意头顶的51h实际上是80的十六进制50h+1。最后1和0代表读写。注意new数组一定要搭配delete,否则只是删除p一次,不是三次。
六、进一步补充namespace
有两种调用方式,一种是直接开头全部声明,一种是部分声明
总结
系统总结了栈、堆,内存管理,以及包括new的剖析。