侯捷C++手把手教学:堆、栈与内存管理

    科技2024-08-21  26

    所谓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的区别: 会影响析构函数的调用次数,对于包含指针的类,不调用析构函数则指针所指向的内存空间没有得到释放。 错误使用会造成内存泄漏,是指针所指向的空间内存泄漏。

    Processed: 0.019, SQL: 8