zoukankan      html  css  js  c++  java
  • 内存分配

    操作系统
      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)




  • 相关阅读:
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 画图(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 相邻数对(暴力)
    Java实现 蓝桥杯 算法训练 Cowboys
    Java实现 蓝桥杯 算法训练 Cowboys
    55. Jump Game
    54. Spiral Matrix
    50. Pow(x, n)
  • 原文地址:https://www.cnblogs.com/ezhong/p/4287705.html
Copyright © 2011-2022 走看看