内存分配

 

操作系统
  VirtualAlloc
    需要程序员控制 内存空间分配 / 页调拨
  HeapAlloc
    程序员不需要处理 内存空间 页 问题 ,但需要自己创建堆 管理堆 销毁堆

    进程创建时有默认堆 .

    程序员可以HeapCreate创建自定义堆

  GlobalAlloc / LocalAlloc
    windows 16位操作系统用 ,已经废弃,但为兼容,仍可用

语言C++
  malloc
    提供动态内存分配

    windows下
      底层调用HeapAlloc
      并不是在进程默认堆申请,而是在运行时库初始化创建的自定义堆分配

  new 操作符

    分两步:
      1. 调用 operator new 分配内存
        operator new 可重载 ,原型是 void * operator new(std::size_t ) throw(std::bad_alloc);


        调用顺序:
          要申请内存的数据类型 T 的内部 operator new
          数据类型 T 所属命名空间的 operator new
          全局 ::operator new

        重载函数一般用 ::operator new / malloc 进行内存分配,加一些自定义内容?
    

        windows vs ::operator new 的默认实现
          Release 模式下调用 malloc
          Debug  模式是调用 _malloc_dbg



      2. 在1分配的内存上初始化对象
        如果调用构造函数初始化对象失败,会自动调用 operator delete() 释放已经分配的内存

    operator new 重载后,要重载对应的 operator delete,原型是 void operator delete(void *) throw();


其他:
  带位置的 new 运算符(placement new)
    语法: new (expression-list) new-type-id(optional-initializer-expression-list);

    expression-list : 实参列表
    new-type-id : 类型
    optional-initializer-expression-list : 构造函数参数

    这种形式的 new 运算符 首先调用 operator new(size_t,OtherTypeList) 来获取内存,
    然后对该对象执行构造函数.

    语义上包括四种使用情形:
      1. 直接给出要构建对象的内存位置
      2. 不抛出异常,如果内存分配失败返回空指针
      3. 定制的/带其他参数的内存分配器
      4. 用于调试目的,在构造函数调用失败时给出源文件名和行号

    一般调用就是指第一种情形,用于在一块内存上调用 构造函数 (因为用户不能显示调用 构造函数 )
    对应的 operator new(size_t,OtherTypeList) 由C++标准库提供实现 头文件<new>

      inline void * operator new(std::size_t,void*__p)throw(){return __p;}
      inline void * operator new[](std::size_t,void*__p)throw(){return __p;}
      inline void operator delete(void *,void*) throw(){}
      inline void operator delete[](void*,void*)throw(){}

    因为通过 placement new 调用构造函数前,已经分配好了原始内存,
     把内存地址通过 new (p) T(value) 传递给 operator new(size_t,void*)
     带位置的 operator new只需要直接返回内存地址就可以

  自定义参数的 operator new
    operator new (size,Type1,Type2,...);




感觉 operator new(size) / operator new(size,void*) 都是自定义参数 operator new 的一种特殊情况

总的来说: new 运算符 会调用 operator new , 然后再调用构造函数

根据new 运算符不同的语法,调用不同的 operator new

  1.普通的new运算符表达式 new Type(init value)

    调用 void * operator new(std::size_t ) throw(std::bad_alloc);

  2.带位置的new运算符表达式 new(ptr) Type(init value)

    调用 void * operator new(std::size_t,void*__p) throw();

    因为是在已经分配好的内容 ptr 上面进行构造,
    所以标准库的 void * operator new(std::size_t,void*__p) 直接返回地址

  3.自行定制参数的new运算符表达式 new (para) Type(init value)

    调用 void * operator new(size, paraType)




你可能感兴趣的:(内存分配)