Loading

C++ stack与heap

stack(栈) heap(堆)
Stack,是存在于某作用域(scope)的一块内存空间(memory space).例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,以及返回地址。

在函数本身(function body)内声明的任何变量,其所使用的内存块都取自于上述stack.

Heap,或者说system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区块(blocks)

class Complex {...};
...
{
Complex c1(1,2);// c1所占用的空间来自stack
Complex * p = new Complex(3); 
//Complex(3)是个临时对象,其所占用的空间是以new自heap动态分配而得,并由p指向
}

stack objects 的生命周期

class Complex{...};
...

{
Complex c1(1,2);
}

c1便是所谓stack object,其生命在作用域(scope)结束时结束。
这种作用域内的object,又称为auto object,因为它会被自动释放。


static local objects 的生命周期

class Complex{...};
...

{
static Complex c2(1,2);
}

c2便是所谓static object,其生命在作用域(scope)结束时仍然存在,直到整个程序结束.

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

int main()
{
...
}

 

c3就是global object,其生命在整个程序结束之后才结束,也可以把它视为一种static object,其作用域是整个程序.


heap objects 的生命周期

class Complex{...};
...


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

 

p所指的是heap object,其生命在它被deleted时结束。

class Complex{...};
...


{
Complex* p = new Complex;
}

 

以上出现内存泄露(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针
p的生命却结束了,作用域之外再也看不到p(也就没机会delete p)了。
尽可能避免这种情况。

new:先分配memory,再调用ctor

Complex * pc = new Complex(1,2);

三个步骤。
编译器转化为:

Complex * pc;

// operator new是C++中的一个特殊函数,其本质也是调用了malloc分配内存
1.void * mem = operator new(sizeof(Complex)); 
2.pc = static_cast<Complex*>(mem); //将mem指针转为Complex类型的指针
3.pc->Complex::Complex(1,2); //构造函数 本质 Complex::Complex(pc,1,2); 这里的pc相当于this,是不可见的

delete: 先调用 dtor,再释放memory

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

编译器转为
String::~String(ps); //析构函数
operator delete(ps); //释放内存,operator delete()是C++中的一个特殊函数其内部调用free(ps)

array new 一定要搭配 array delete

String * p = new String[3];
...
delete[] p; //唤起3次dtor

String * p = new String[3];
...
delete p; //唤起1次dtor

 

posted @ 2021-01-13 17:03  eveilcoo  阅读(264)  评论(0编辑  收藏  举报