P8 堆、栈与内存管理

P8 堆、栈与内存管理


1、所谓stack,所谓heap

Stack:是存在于某个作用域的一块内存空间。例如当你调用函数,函数本身即会形成一个stack用来存放它接受的参数,以及返回地址。
在函数本体内声明的任何变量,其所使用的内存都取自上述stack。

Heap:指由操作系统提供的一块全局内存空间,程序可自动分配,从中获得若干块。

class Complex{...};
...
{
    Complex c1(1 , 2);//在栈中获得,离开作用域自然消亡。
    Complex* p = new Complex(1 , 2);//从堆中申请一块空间,需要手动delete,否则离开作用域无法找到。
}
-----------------

1.1.stack objects的生命周期

class Complex{...};
...
{
    Complex c1(1 , 2);
}

c1便是所谓的stack object,其生命在作用域结束之后结束。
这种作用域内的object,又称为auto object,因为它会被自动清理。


1.2static local object

class Complex{...};
...
{
    static Complex c2(1 , 2);
}

c2便是所谓的static object,其生命在作用域结束之后仍然存在,知道整个程序结束。


1.2 static local object

class Complex{...};
...
{
    static Complex c2(1 , 2);
}

在加入static关键字后,c3成为了global object,其生命在整个程序结束之后才是结束。


1.3 global object的生命期

class Complex{...};
...
Complex c3(1 , 2);
int main()
{
...
}

c3便是所谓的global object,其生命在整个程序结束之后才结束。可以把它视为一种static object。这就联想到整个对象的构造函数和析构函数什么时候被调用


1.4 heap objecs的生命期

class Complex{...};
...
{
	Complex* p = new Complex;
	...
	delete p;
}

p指向的就是heap object,其生命在它被delete之后结束

class Complex{...};
...
{
	Complex* p = new Complex;
	...
}

第二种操作会出现内存泄漏,因为在作用域结束之后,p所指向的heap object仍然存在,但指针p的生命已经结束了,作用域之外再也看不到p,也就无法delete p了。


2、new:先分配内存,再构造函数

new的真实过程

Complex* pc = new Complex(1 , 2);
=>
编译器转化为:
void* mem = operator new(sizeof(Complex)); //分配内存,内部调用malloc(n)
pc = static_cast<Complex*>(mem);           //转型
pc->Complex::Complex(1 , 2);               //构造函数,实际上Complex::Complex(pc,1,2);

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

delete的真实过程
对于Complex这类不带指针的类,没必要进行析构,因为它存放的仅是值而已;
但是对于String这类带指针的类,必须要析构,因为这类对象本身会去动态申请空间,所以得先将自身申请的空间释放。

delete ps;
=>
编译器转化为:
String::~String(ps); //析构函数,先将自身动态分配的内存释放
operator delete(ps); //释放内存,内部调用free(ps)

2、动态分配所能得的内存

上下两块红色表(cookie)示边界,其中红色的最后一位(1/0)表示是分配,还是收回;
灰色:调试模式下的额外空间,便于顺利回收
浅绿色:数据
绿色:补全,因为空间分配需要是16的倍数
在这里插入图片描述

2、动态分配所能得到的数组

动态分配得到的内存情况在这里插入图片描述
new的是数组,那么delete的也要是数组,否则会造成内存泄漏(数据)。
虽然delete p同样可以根据cookie找到对应的内存,但是对于内部的若干存放数据的内存,只会调用一次dtor。因此此时泄露的是灰色那一部分,而cookie中其余部分会被正常释放。
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值