When is the constructor called by 'new' op

2020-07-27 16:03发布

问题:

Since I started learning C++, I have always read that the 'new' operator calls the constructor of the object before returning the pointer to the allocated memory.

So, out of curiosity I checked the source code for 'new' and I found the following at http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/new_op.cc?revision=197380&view=markup

_GLIBCXX_WEAK_DEFINITION void *
    operator new (std::size_t sz) _GLIBCXX_THROW (std::bad_alloc)
    {
      void *p;

      /* malloc (0) is unpredictable; avoid it.  */
      if (sz == 0)
        sz = 1;
      p = (void *) malloc (sz);
      while (p == 0)
        {
          new_handler handler = std::get_new_handler ();
          if (! handler)
            _GLIBCXX_THROW_OR_ABORT(bad_alloc());
          handler ();
          p = (void *) malloc (sz);
        }

      return p;
    }

I do not see any constructor being called or any sort of mechanism to identify the type of object.

So, how is this done? Does the compiler play some trick by calling the constructor on the allocated memory? Any help will be appreciated.

Also, in case of new[] (at link below), no entry is being made to keep track of the number of elements in the array. So, how does delete[] know how many elements to be destructed?

http://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/new_opv.cc?revision=195701&view=markup

I went through many related questions on SO and also googled it, but could not find an answer.

回答1:

I do not see any constructor being called or any sort of mechanism to identify the type of object.

The job of the operator new function is just to allocate memory; it doesn't call a constructor, and doesn't even know what type of object (if any) will be constructed in the memory. It's just told how many bytes to allocate.

Does the compiler play some trick by calling the constructor on the allocated memory?

If by "play some trick", you mean "generate some code", then yes. If you use a new-expression to create an object, then it does two things:

  • Calls operator new() to allocate enough memory for the object;
  • Calls a constructor to initialise an object in that memory.

Also, in case of new[] (at link below), no entry is being made to keep track of the number of elements in the array. So, how does delete[] know how many elements to be destructed?

The new[] expression (not operator new[]) will record that somewhere. The exact details are left to the implementation.



回答2:

Does the compiler play some trick by calling the constructor on the allocated memory?

Yes, the operator new that is seen above is only the implementation of the part that gets the memory block. When using new T in your code, the compiler invokes the appropriate operator new (size_t) implementation to get a memory block, and then calls the T constructor on it.