C++ 内存管理之operator new

本文详细介绍了C++中的new和delete表达式以及operatornew函数的工作原理。newexpression用于动态分配内存并构造对象,而deleteexpression负责调用析构函数并释放内存。operatornew作为内存分配的底层实现,包括了常规分配、nothrow分配和放置(new)分配三种版本。放置(new)允许在已分配的内存上初始化对象,但需要手动调用析构以避免内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 内存管理之operator new

C++提供了new和delete方式来申请和释放堆区内存,但new和delete是指的expression,而底层是operator new函数。下面来区分一下这几个概念。

  • new/delete expression

    new expression动态分配内存,delete expression释放内存。网上也有说是new operator的,这种说法属实容易让人误解​.​.​.😅

    • new expression的行为分析

      1. 通过调用合适的内存分配函数,也就是operator new()

      2. void指针转型和初始化对象,类似于

        A* p = static_cast<A*>(::operator new(size))p->A();
        

        但是用户不能直接这样调用,只能用placement new,即new(static_cast<A*>p) A()

      A* p = new A;
      	  // allocates memory by calling: operator new (sizeof(A))
            // and then constructs an object at the newly allocated space
      
    • delete expression的行为分析

      1. 调用析构
      2. 释放内存
    • placement new

      在已分配的内存空间上,初始化对象(调用构造函数)

      如果给new-expression提供了placement-params(指针),这个参数会作为placement new版本的operator new的额外参数,具体为void* operator new(std::size_t, void*),这个函数只是返回第二个参数。

      注意这种方式,需要手动调析构函数,否则可能会内存泄露

      // within any block scope...
      {
          alignas(T) unsigned char buf[sizeof(T)];
          // Statically allocate the storage with automatic storage duration
          // which is large enough for any object of type `T`.
          T* tptr = new(buf) T; // Construct a `T` object, placing it directly into your 
                                // pre-allocated storage at memory address `buf`.
          tptr->~T();           // You must **manually** call the object's destructor
                                // if its side effects is depended by the program.
      }                         // Leaving this block scope automatically deallocates `buf`.
      
  • operator new

    allocation functions,<new>中给出了三个版本

    throwing (1)	
    void* operator new (std::size_t size);
    nothrow (2)	
    void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
    placement (3)	
    void* operator new (std::size_t size, void* ptr) noexcept;
    

    第一个版本,分配size字节的空间,失败throw std::bad_alloc

    第二个版本,分配size字节的空间,不抛出异常,return null

    第三个版本,直接返回ptr,当使用new-expression调用此版本时,是placement new

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值