• C++ 之 new


    new的类型

    有三种类型的new,名字都是new,用起来也都跟分配内存有关系,分别是plain new , nothrow new和 placement new。看如下代码:

    class MyClass {…};
    MyClass * p=new MyClass;


    这里的new实际上是执行如下3个过程(这三个过程都在一个new operator中完成):
    1. 调用malloc/heap_alloc分配内存 ;2. 调用构造函数生成类对象;3. 返回相应指针。

    operator new就像operator+一样,是可以重载的,但是不能在全局对原型为void operator new(size_t size)这个原型进行重载,一般只能在类中进行重载,也可以重载全局的operator new,来实现对程序所有的new有统一的行为。nothrow operator new是跟plain new同等地位的,也是可以重载的。如果类中没有重载operator new,那么调用的就是全局的::operator new来完成堆的分配。同理,operator new[]、operator delete、operator delete[]也是可以重载的,一般你重载的其中一个,那么最好把其余的三个都重载一遍。

    placement new 不一样的地方就是它不能被重载, 而new 和nothrow new是可以的。

    new

    void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
            {       // try to allocate size bytes
            void *p;
            while ((p = malloc(size)) == 0)
                    if (_callnewh(size) == 0)
                    {       // report no memory
                    static const std::bad_alloc nomem;
                    _RAISE(nomem);
                    }
     
            return (p);
            }

    nothrow new

    void * __CRTDECL operator new(size_t count, const std::nothrow_t&)
        _THROW0()
        {    // try to allocate count bytes
        void *p;
        _TRY_BEGIN
        p = operator new(count);
        _CATCH_ALL
        p = 0;
        _CATCH_END
        return (p);
        }

    placement new

    inline void *__CRTDECL operator new(size_t, void *_Where) _THROW0()
        {    // construct array with placement at _Where
        return (_Where);
        }
     

    标准C++ new失败后抛出标准异常std::bad_alloc异常,在一定的环境下,返回一个NULL指针来表示一个失败依然是一个不错的选择。C++标准委员会意识到这个问题,所以他们决定定义一个特别的new操作符版本,这个版本返回0表示失败。于是设计了nothrow new。他们的区别就是nothrow new失败时不抛出异常,而是返回NULL。再看看nothrow new的原型:

    void * __CRTDECL operator new(size_t count, const std::nothrow_t&)

    nothrow_t

    Type of the nothrow constant.
    This is a type specifically designed to overload the dynamic memory allocation operator functions operator new, operator new[] , operator delete and operator delete[] .
    It is an empty class defined in the <new> header. This header also defines the standard constant nothrow, which is a value of this type specifically designed to call the overloaded operator functions.

     

    Nothrow constant

    This constant value is used as an argument for operator new and operator new[] to indicate that these functions shall not throw an exception on failure, but return a null pointer instead.

    bad_alloc

    Type of the exceptions thrown by the standard definitions of operator new and operator new[] when they fail to allocate the requested storage space.
    This class is derived from exception.

     

    new_handler

    typedef void (*new_handler)();

    Type of new handler function

    This is a typedef of a void function with no parameters, used as the argument and return type in function set_new_handler.
    A new handler function is a function that is called by the standard definition of functions operator new or operator new[] when they are not successful allocating memory.

     

    set_new_handler

    new_handler set_new_handler (new_handler new_p) throw();

    Sets new_p as the new handler function.
    The new handler function is the function that is called by functions operator new or operator new[] when they are not successful in an attempt to allocate memory.
    The new handler function can make more storage available for a new attempt to allocate the storage. If, and only if, the function succeeds in making more storage avaible, it may return. Otherwise it shall either throw a bad_alloc exception (or a derived class) or terminate the program with cstdlib's abort or exit functions.
    If the new handler function returns (i.e., it made more storage available), it can be called again if the operator new or operator new[] function is again not successful attempting to allocate the storage. This may repeat itself until either the allocation is successful or thehandler function fails.   

    使用new时的初始化

    在使用new分配内存单元时,一般希望新分配的单元能被初始化为全0。注意以下两条语句:

    int *ptrInt1 = new int; //新分配的内存单元里的值是未知
    int *ptrInt2 = new int(); //加上括号。新分配的内存单元里的值是全0

    这个括号意味着是什么?它是C++中一个不太引人注意的feature,叫做value-initialize。可以参考http://en.cppreference.com/w/cpp/language/value_initialization

  • 相关阅读:
    服务器负载均衡的基本功能和实现原理
    几种负载均衡技术的实现
    Postman-CI集成Jenkins
    Postman-进阶
    Postman-简单使用
    chrome安装插件,安装Postman
    关于angularjs dom渲染结束再执行的问题
    Protractor(angular定制的e2e)的简易入门
    关于ng-router嵌套使用和总结
    scss使用后的简单入门总结
  • 原文地址:https://www.cnblogs.com/whyandinside/p/2339102.html
Copyright © 2020-2023  润新知