C++【侯捷】——— 堆、栈与内存管理

C++【侯捷】——— 堆、栈与内存管理

Stack

class Complex { ... };
...
Complex c3(1,2);
void main()
{
    Complex c1(1,2);
    static Complex c2(1,2);
    Complex* p = new Complex(3);  //heap
}

Stack栈:是存在于魔偶作用域的一块内存空间,函数本身会形成一个stack,存放接收的参数和返回地址以及local object。c1所用的空间来自stack。器生命在作用域之内有效,会自动清理,析构函数自动调用。
static object,生命在作用域结束之后仍然存在,析构函数在整个程序结束时调用。
golbal object:在程序结束时调用析构函数。

Heap

Heap堆:是指有操作系统提供的一块全局内存空间,可以通过动态分配来获取。p所指向的空间来之heap。

new

new:先分配memory,在调用构造函数
COmplex* pc = new Complex(1,2);

  1. void*mem = operator new(sizeof(Complex)); 其内部调用malloc()
  2. pc = static_cast<Complex*>(mem); 进行了一个转型
  3. pc->Complex::Complex(1,2); 调用构造函数,构造函数的全名:Complex::Complex(pc,1,2);pc是个隐藏的参数,通过this指针指向。

delete

delete:先调用析构函数,再释放内存

String* ps = new String("Hello");
...
delete ps;

1.String::~String(ps); 编译器给的析构函数时没有做什么事情的,对之前自己写的String类中,析构函数将String类中动态分配的内存释放掉。
2.operator delete(ps); 其内部调用free(ps),把字符串本身free,其中只有一个指针。

VC中内存分配

用VC的调试模式可以看到new分配的内存地址。new一个变量之后,除了得到本身的大小,还会得到前面32个后面4个以及前后各一个cock(4个字节),VC中每一块都是16的倍数,如果总和不够,还要填补一些空间进去。多的时给释放的时候用的,在vc的非调试模式下没有前后32+4的字节空间只有前后的cock,cock中记录了分配的空间大小,但是都是16的倍数,最后四位都是零,借以为来记录是还进来还是给出去,还进来是0,给出去是1.

new的时候用[],delete的时候也要用[],这是数组形式的。VC中数组在分配内存的时候,在存数据的前面会加4个字节,用来记录数组元素的个数。如果不搭配中括号[]会造成内存泄漏。上面delete中第二步删除的时候会看cock,将整个块删除。加上中括号,编译器会知道调用调用多次析构函数,将动态分配的内存删掉,如果不加中括号,只会调用析构函数一次,后面的部分就不会删掉。如果类的成员中没有指针,就不会存在这种情况,加不加中括号都会删掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值