• 条款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 };
  • 相关阅读:
    sql server 分页
    省市区
    省市
    sql server 中英混合排序
    C# 添加大量sql
    小程序小数的输入判定
    C# Files 的值“<<<<<<< .mine”无效。路径中具有非法字符。
    vagrant安装遇到的问题
    vagrant安装使用
    tp6 session问题
  • 原文地址:https://www.cnblogs.com/-wang-cheng/p/4889912.html
Copyright © 2020-2023  润新知