search

Home  >  Q&A  >  body text

c++ 中new 操作符是怎么实现的

c++ 中new 操作符是怎么实现的

PHP中文网PHP中文网2814 days ago626

reply all(3)I'll reply

  • PHPz

    PHPz2017-04-17 11:06:12

    First of all, we need to distinguish between the two concepts new operator and operator new.

    The former is the new 操作符 in the question.

    Generally, when new an object, the bottom layer does the following two steps:

    1. Allocate memory for the object;

    2. Call the constructor to initialize this memory;

    In the first step, memory is allocated using operator new . @Feixia’s second example is a operator new.
    In the second step, call the constructor to initialize the memory. If inheritance is not involved, this step is very simple, just assign a value to the memory. Even if there is an inheritance relationship, the complexity lies in sorting out the inheritance relationship and virtual function table, which has little to do with this question.

    The following focuses on operator new in the first step. Its responsibility is to allocate memory.

    The general processing flow of

    operator new is as given in @Feixia’s second example:

    1. allocates memory and returns directly if successful, otherwise,

    2. Check whether new_handler is available, if available, call it and jump to 1, otherwise,

    3. throws bad_alloc exception.

    The above new_handler will try to free some memory.

    After understanding this process, let’s extend the discussion to two other issues.

    1. Does the null check in the following code snippet make sense?

         Question * q = new Question;
         if (q == NULL ) {
             // 错误处理逻辑
         }
      

      We learned from the above that operator new will call new_handler when allocating memory fails to try to let the system release some memory, and then try to apply for memory again. If the memory in the system is really tight at this time, even if new_handler is called, the system will not be able to get more memory, which will cause operator new to fall into an infinite loop.

      In short, operator new either the memory is successfully applied for, or the endless loop fails.

      Then, consider the second step of new operator, calling the constructor to initialize the memory. As we all know, the C constructor does not return any return value. If you want the constructor to fail, you can only throw an exception.

      From the above two points we can draw the conclusion: new Question will never return a null pointer.

      Furthermore, new Question can fail in only two cases:

      1. operator new throws bad_alloc exception;

      2. The constructor throws its own exception.

      So, does the null judgment logic in the above code snippet make sense? Is using try ... catch to catch the exception of new a better way to judge the failure of new?

    2. Customized memory management

      Generally those who want to create new ones want to implement their own memory management (such as using a memory pool), and want to allow old code to enjoy the benefits of new memory management without changing the existing code. Welfare.

      The specific method has been explained very clearly in the second article quoted by @Feixia. But because overloading new operator may have a much greater impact on the entire system than initially imagined, the following two compromise solutions can be considered:

      1. use placement new;

      2. Implement a new New (rather than overloading the original operator new) and use it where really needed.

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:06:12

    new is a language feature of C , not a function.

    It may call malloc, but how to allocate memory depends on the implementation. Compared with malloc, new will throw an exception by default when the application fails instead of returning 0 directly.

    corresponds to new and delete, and they must appear in pairs. new[] and delete[] must appear at the same time.

    reply
    0
  • 迷茫

    迷茫2017-04-17 11:06:12

    New is a C keyword. You can try to implement a new yourself. If necessary, use your own implemented functions to replace the default new to do some checks and other things.
    For example, the writing method in the following link
    cppreference link

    void* operator new(std::size_t sz) {
        return std::malloc(sz);
    }
    

    Implementation of complex points - in-depth exploration of C 's new/delete operator - Author @Kelvin

    BLOG link, infringement and deletion

    void * operator new(std::size_t size) throw(std::bad_alloc) {
        if (size == 0)
            size = 1;
        void* p;
        while ((p = ::malloc(size)) == 0) {
            std::new_handler nh = std::get_new_handler();
            if (nh)
                nh();
            else
                throw std::bad_alloc();
        }
        return p;
    }
    
    void operator delete(void* ptr) {
        if (ptr)
            ::free(ptr);
    }
    

    Added new_handler function to deal with insufficient memory

    reply
    0
  • Cancelreply