zoukankan      html  css  js  c++  java
  • 条款52:谢了placement new 也就同时应该写一个placement delete

    如果operator new接收到的参数除了size_t之外还有其他的话,那么这个operator new实际上就是一个placement new,所以考虑下下面这样的情况:

    一个可以用来记录信息的placement new:
    1 class Widget{
    2 public:
    3     ...
    4     static void * operator new(std::size_t size, std::ostream & logStream = std::cout) 
    5         throw(std::bad_alloc);
    6     static void * operator delete(void * pMem, std::size_t size) throw();
    7     ...
    8 };

    那么当我们新建一个Widget的时候:

    1 Widget * wgt = new (std::cerr)Widget;
    这时,如果在new的时候成功但是在构造Widget的时候失败,那么系统寻找不到相应的delete可以将分配的raw内存释放掉,这样就会引起内存泄漏了。
     
    所以在提供placement new 的时候一定要提供相应的placement delete,这样就不会发生内存泄漏。
    placement delete如下所示:
    1 static void operator delete(void * pMem, std::ostream& logStream);

    完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.完成所有的要点的简单的形式是,建立一个base class, 内含有所有正常形式的new以及delete.

     1 class StandardNewDeleteForms{
     2 public:
     3     //normal new / delete
     4     static void * operator new(std::size_t size) throw(std::bad_alloc)
     5     {
     6         return ::operator new(size);    //这里使用的是全局的new
     7     }
     8     static void operator delete(void * pMem) throw()
     9     {
    10         return ::operator delete(pMem);
    11     }
    12     //placement new / delete
    13     static void * operator new(std::size_t size, void * ptr) throw()
    14     {
    15         return ::operator new(size, ptr);
    16     }
    17     static void operator delete(void * pMem, void * ptr)throw()
    18     {
    19         return ::operator delete(pMem, ptr);
    20     }
    21     //nothrow new/delete
    22     static void * operator new(std::size_t size, const std::nothrow_t & nt) throw()
    23     { return ::operator new(size, nt);}
    24     static void operator delete(void * pMem, const std::nothrow_t & nt) throw()
    25     { return ::operator delete(pMem, nt)}
    26 };

    然后既可以使用继承以及using声明获得想要的new以及delete:

    1 class Widget : public StandardNewDeleteForms{
    2 public:
    3     using StandardNewDeleteForms::operator new;
    4     using StandardNewDeleteForms::operator delete;    //将他们引入作用域,以免全局的new以及delete被遮盖的掉。
    5     static void * operator new(std::size_t size,
    6                         std::ostream & logStream) throw(std::bad_alloc);
    7     static void * operator delete(void * pMem, 
    8                         std::ostream & logStream) throw();
    9 };
  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889912.html
Copyright © 2011-2022 走看看