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)




  • 相关阅读:
    字典常用操作复习
    列表常用方法复习
    爬虫流程复习
    协程解决素数
    yield 复习
    多线程复习2
    多线程复习1
    异常 巩固3
    logging日志基础示例
    2019最新百度网盘不限速下载教程
  • 原文地址:https://www.cnblogs.com/ezhong/p/4287705.html
Copyright © 2011-2022 走看看