1

I was analyzing the vector class. Then, I can find this sytax

(first new syntax)

void construct(pointer __p, const _Ty& _Val)
    {new ((void *)__p) _Ty(_Val)};

template<typename _Up, typename ... _Args>
    void construct(_Up* __p, _Args&&... __args)
    {new ((void *)__p) _Ty(_STD forward<_Args>(__args)...)};

And I can understand this don't equal to

     __p = new _Ty(_Val);

then What is the difference between the two statements and, how should i interpret the first new syntax? (IN VisualStudio2013)

rollrat
  • 151
  • 13

3 Answers3

3

It's known as placement new. Rather than allocating memory for the object, as a regular new-expression does, it constructs it in the memory that the pointer points to.

The vector does this in order to separate memory allocation from object construction; calling reserve can allocate enough memory for many elements, but leave it empty until the vector grows into that memory.

If you create an object like this, then it has to be destroyed with an explicit call to its destructor:

__p->~_Ty();
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1
  __p = new _Ty(_Val);

means allocate a block of memeory (via malloc), construct a _Ty object in that space (using _Val). Store the address of the allocate & constructed block in __p.

 new ((void *)__p) _Ty(_Val)

means memory is already allocated at the address __p, construct a _Ty object in that space (using _Val)

James Curran
  • 101,701
  • 37
  • 181
  • 258
1

What is the difference between the two statements

The code construct:

new (<address>) <typename>{ <arguments> };

is called "placement new". Contrary to the default new (i.e. same without the address), this call doesn't allocate memory at all, but assumes the <address> is to already allocated memory (that is large enough) and simply constructs the object at the provided address.

This is not the only special case for the new operator. You can also pass an allocator, or some other (random) contextual information to new.

In order for new to support this (passing other information to the operator) you must define a custom operator new implementation, that receives the extra information as parameters. To see in detail how to do this, check online (search for "custom operator new", "placement new" and "define custom operator new"). Note that implementing a custom new operator has some pitfalls for implementing correctly. This is why you should read more about it if you plan to define it.

The standard library, implements by default new, placement new and (I think) a new that supports a std::allocator instance.

utnapistim
  • 26,809
  • 3
  • 46
  • 82