C++ separates the notions of memory allocation and object lifetime. This is perhaps one of the most important "new" aspects of the language compared to C. In C there is no such distinction because variables are entirely determined by their memory, while in C++ objects have a more abstract notion of a "state" which is distinct from the underlying memory.
Let's look at memory first:
{ char buf[100]; // automatic allocation, scoped lifetime } { void * p = std::malloc(100); // dynamic allocation, manually managed void * q = ::operator new(100); // essentially identical // ... ::operator delete(q); // manual deallocation std::free(p); // ditto }
On the other hand, an object's lifetime is a separate topic:
{ Foo x; // automatic storage, scoped lifetime. // Implies automatic memory allocation for sizeof(Foo) bytes. } { Foo * px = ::new Foo; // dynamic storage, manual lifetime, // implies dynamic allocation via ::operator new() Foo * py = ::new (q) Foo; // dynamic storage and manual lifetime, uses memory at q // ... delete px; // destroy object _and_ deallocate memory py->~Foo(); // destroy object. Memory was never our business to start with. }
As you can see, the separation of memory and object lifetime adds a lot of flexibility: We can have dynamic objects living in automatic memory, or take care of allocation ourselves and reuse memory for repeated object constructions. The standard new and delete expressions combine allocation and construction, but this is only a shortcut for the most frequently used operations. In principle, you're entirely free to handle memory and object lifetime separately.
This idea underpins the notion of allocators, which are a core concept in the C++ standard library.
a's memory to place p into it.