所谓stack(栈),所谓heap(堆) Stack:是存在于某作用域(scope)的一个内存空间(memory space)。例如当你调用函数,函数本身即会形成一个stack用来放置它所接收的参数,返回地址,及局部对象(local object)。 Heap:或称system heap,是指由操作系统提供的一块global内存空间,程序可动态分配(dynamic allocated)从中获得若干区域(blocks)。 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)结束之后仍然存在,直到整个程序结束。 global objects的生命期
class Complex { ... }; ... Complex c3(1,2); int main() { ... }c3便是所谓global object,其生命在整个程序结束之后才结束。也可以把它视为一种static object,其作用域是整个程序。 heap objects的生命期 正确写法:
class Comliex { ... }; ... { Complex* p = new Complex; ... delete p; }p所指的便是heap object,其生命在它被delete之际结束。 错误写法:
class Complex { ... }; ... { Complex* p = new Complex; }以上出现内存泄漏(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p。 new:先分配memory,再调用ctor
Complex* pc = new Complex(1,2);编译器转换为:
Complex *pc; void* mem = operator new( sizeof(Complex) ); //分配内存,其内部调用malloc(n) pc = static_cast<Complex*>(mem); //转型 pc->Complex::Complex(1,2); //构造函数delete:先调用dtor,再释放memory
String* ps = new String("Hello"); ... delete ps;编译器转化为:
String::~String(ps); //析构函数,释放指针所指的空间 operator delete(ps); //释放内存,释放指针;内部调用free(ps)内存管理 操作系统&最后一位为0,则表示可以回收,可以覆盖使用;为1的话就不能覆盖。 array new一定要搭配array delete。 delete[] p和delete p的区别: 会影响析构函数的调用次数,对于包含指针的类,不调用析构函数则指针所指向的内存空间没有得到释放。 错误使用会造成内存泄漏,是指针所指向的空间内存泄漏。