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