Stack & Heap | 青训营笔记

63 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的的第4天。

Stack 栈

  • 栈一般用于存储参数/局部变量/函数调用后返回地址
  • FIFO 先进后出
  • 栈指针
    • 指向栈顶
    • 一般存储在寄存器
  • 由高地址向低地址扩展

Heap 堆

  • 存储数组和对象, 线程共享
  • Heap数据结构无关,OC底层用双向链表实现
  • 手动分配
  • 由低地址向高地址扩展

C & C++ 内存管理

C 内存管理

  • malloc & free 动态分配内存
void stackFunc() {
        // they are all in stack
        int a = 10; 
        char s[] = "aa";
        printf("the a is %d\n", a);

}

void heapFunc() {
        // b is in heap
        int* b = malloc(sizeof(int));
        printf("the b is %d\n", *b);
        free(b);
}

C++ 内存管理

  • new & delete
    • malloc/free只是动态分配内存空间/释放空间,new/delete 还会调用构造函数和析构函数进行初始化与清理
    • malloc/free需要手动计算类型大小,new/delete可自动计算类型的大小
    • malloc/free管理内存失败会返回0new/delete等的方式管理内存失败会抛出异常
void useRawPointer()
{
    // Using a raw pointer -- not recommended.
    std::string *pSong = new std::string("Nothing on You");
    int *p = new int[10];
    
    std::cout << *pSong << std::endl;

    // Don't forget to delete!
    delete pSong;
    delete[] p;
}
  • Smart Pointer 智能指针

    • 保留 ->* 运算符
    • auto_pt & unique_ptr
      • 基于排他所有权模式:两个指针不能指向同一个资源
      • 无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值
    • shared_ptr
      • 可以复制赋值操作
  • Reference Counting 引用计数

    • 记录了当前内存资源有多少指针在引用(可以访问这个资源)
    • 当新增加一个可以访问这个资源的引用,计数器会加1,反之会减1
    • 当引用计数等于0时,对象会被销毁
shared_pt<Person> sp1;
shared_pt<Person> sp2(new Person(2));

// 获取智能指针管控的共享指针的数量  use_count():引用计数
cout << "sp1    use_count() = " << sp1.use_count() << endl; // 0
cout << "sp2    use_count() = " << sp2.use_count() << endl << endl; // 1

sp1 = sp2; // 共享

cout << "sp1    use_count() = " << sp1.use_count() << endl; // 2
cout << "sp2    use_count() = " << sp2.use_count() << endl << endl; // 2

shared_pt<Person> sp3(sp1);
cout << "sp1    use_count() = " << sp1.use_count() << endl; // 3
cout << "sp2    use_count() = " << sp2.use_count() << endl; // 3
cout << "sp3    use_count() = " << sp3.use_count() << endl << endl; // 3