zoukankan      html  css  js  c++  java
  • C++ 关键字 new

    new

    new 是C++ 中的关键字,有两个含义

    1. new 表达式
    2. 作为运算符的函数名,也就是 operator new

    new 表达式

    提供一个特定的内存分配格式,返回在存储空间上构造的对象或对象数组的一个 纯右值 指针。

    语法

    • :: (可选) new (布置参数)(可选) (类型) 初始化器(可选)
    • :: (可选) new (布置参数)(可选) 类型 初始化器(可选)

    说明

    1. 布置参数为分配的内存
    2. 初始化器则有两种,分别是(){} 初始化方式,可以包括 auto decltype(auto) 等占位类型说明符
    char* ptr = new char[sizeof(T)]; // 分配内存
    T* tptr = new(ptr) T;            // 在已分配存储中构造(“布置”)
    tptr->~T();                      // 销毁
    delete[] ptr;                    // 解分配内存
    

    一些注意点

    1. 表达式中的 类型为贪心,比如 new int * 1 实际上是 int 先结合 *,(这个会编译失败)。
    2. 在对象数组分配内存时,一维之外的维数必须指定为整数常量。
    3. new 表达式是为对象分配是调用 operator new 来完成,对象的大小可以在编译期得到 (开优化),之后进行对象的构造,构造过程的规则无特殊之处。

    operator new

    new 表达式通过调用 operator new 来分配内存,分配对象数组为 operator new[].

    C++ 自身提供了全局的函数(以::开始),和用户自定义的替换函数,如果 new T; 中T为类类型,则从T的类作用域中开始查找替换函数。

    基本的函数格式如下:

    void* T::operator new  ( std::size_t count );
    

    这里我们自定义一个例子,operator new 是我们自定义的分配函数,后面部分是对在已经分配的内存上进行再分配的情况

    • 在已有内存上分配空间,不会再调用分配函数,
    • 每次分配的内存地址都相同。
      所以每次调用默认布置分配函数的时候,只是一个内存控制权的转移,这段内存的生命生命周期应该在其上构造对象之后。
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    
    void *operator new(size_t n) {
        printf("operator new: %zu
    ", n);
        return std::malloc(n);
    }
    struct Foo {
        uint64_t valu64;
        int64_t vali64;
        char ch;
    
        Foo() : valu64(1), vali64(3), ch('c') {}
    };
    
    int main() {
        char *ptr = new char[16]; // std::malloc(16);
        Foo *tptr = new (ptr) Foo; // 在已分配存储中构造(“布置”), 这里有溢出风险
        tptr->~Foo(); // 销毁
        delete[] ptr; // 解分配内存
    
        Foo *fp = new Foo; // std::malloc(24);
    
        char arr[36];
        printf("init arr addr: %p
    ", arr); // 0x7ffe8f9748e0
        Foo *fptr = new (arr) Foo;
        printf("Foo addr: %p
    ", fptr); // 0x7ffe8f9748e0
        char *ch = new (arr) char;
        printf("ch addr: %p
    ", ch); // 0x7ffe8f9748e0, 三者的地址是一样的
        fptr->~Foo();                // 销毁
    }
    

    参考

    1. new. C++ 关键字 new.

    // 过年疫情导致不能出门,在家里学习学习,记点笔记。

  • 相关阅读:
    P3302 [SDOI2013]森林
    P2542 [AHOI2005] 航线规划
    P5795 [THUSC2015]异或运算
    P3320 [SDOI2015]寻宝游戏
    P1963 [NOI2009] 变换序列
    一月练习日志
    计算几何全家桶
    bzoj1076: [SCOI2008]奖励关(期望dp+状压dp)
    bzoj3450 Easy(概率期望dp)
    Eclipse配置 自动补全功能 快捷键 alt+/
  • 原文地址:https://www.cnblogs.com/shuqin/p/12234739.html
Copyright © 2011-2022 走看看