Pointer Arithmetic 指针运算

image.png
image.png

C-Style Arrays

Avoid — But Know Your Enemy 避免使用c-style的数组

  • C-Arrays on stack

    double a[3] {1.0, 1.2, 5.4};
  • C-Arrays on heap

    auto a = make_unique<double[]>(3);
  • Pass C-Arrays to Function

    //array 衰退(decays to)到指针,由于无法知道数组size,需要额外传递一个参数
    void print (double* x, int n){
    }
    double a[3] {1.0, 1.2, 5.4};
    print(a, 3);
  • copy(@beg, @end, @out)
  • 为什么要避免使用C-Arrays
    1.不是深拷贝/赋值
    2.decays into pointers to first elementss
    3.数组本身不知道它自己的size
  • Strings in C
    1.C-Arrays of characters
    2.以'\0'终止每个character
    3.literal “xyz” 的类型为char const[]

    Manual Memory Management手动内存管理

    T* p = new T{args...}; //alloc object on the heap
    delete p; //free object
    //p 被叫做 owning raw pointer 原始指针
  • Never 手动管理内存,除非你在实现自己的数据结构的过程中,即使这样你也应该使用std::allocator_traits来管理内存
  • c++11之前的黑暗年代,大量滥用原始指针,造成很多问题,在modern c++中用智能指针,自动的delete object,不会造成内存泄漏
  • Valgrind

    • valgrind [options] ./programe [programe options]
      --help
      --tool=memcheck
      --lead-check=full
      -v / --verbose
  • Exceptions 异常

    #include <exception> //utilities for handling
    #include <stdexcept> //predefined rypes
  • std::bad_alloc
  • std::bad_new_array_size

  • 智能指针&异常安全

    //使用make_unique,make_shared 而不是裸指针
    //有内存泄漏风险,Widget{}
    void foo(unique_ptr<Widget> w, Gadget g){...}
    foo(new Widget{}, Gadget{});
    //无内存泄漏
    void foo(unique_ptr<Widget> w, Gadget g){...}
    foo(make_unique<Widget>(), Gadget{});
  • 关于指针实际的使用场景,一直不是很清晰,知道看到了下面这个例子

    class T3;
    class T2;
    class T1;
    class A
    {
    T3* m_t2;//创建和释放都由A之外的代码管理,A只负责(借用)使用;业务逻辑上保证A在使用m_t2指向的对象的时候,对象始终是存在的
    shared_ptr<T2> m_t2;//由加载程序创建m_t2指向的对象,执行时,交给A来管理,涉及动态对象的管理权的交接
    unique_ptr<T1> m_t1;//A管理该对象的生命周期,A的构造函数构造m_t1, A的析构函数释放m_t1;
    };

Allocators

  • 提供内存分配策略的通用接口
    image.png
  • Interface 接口

    template<class T>
    class MyAllocator{
    public:
    T* allocate(std::size_t n);
    void deallocate(T*, std::size_t n);
    }
  • delegate to new/delete

    template<class T>
    class MyAllocator{
    public:
    T* allocate(std::size_t n){
        return new T[];
    }
    void deallocate(T*, std::size_t n){
        delete[] p ;
    }
    }

    - 后面的讲道理没怎么搞明白,懒癌犯了再说吧


ysysys
10 声望1 粉丝