C++ - A Heap vs. Free Store question

Started by
9 comments, last by ToohrVyk 15 years, 10 months ago
Hello folks, another question: Currenrly, I'mr reading Sutters book and he describes fress store objects as objects that "can have memory allocated, without being immediately initalized". The only point of time where I can imageine a free store object to be allocated but not initialized is when the program crashes or throws an exception while processing the initializer list. Is it meant like that or are there more possibilities? Second, he mentions this as a specific free store attribute. But isn't it a heap attribute too since you can allocate space at will and then call the constructor explicitly, which you can not do with new? Thanks for your admittance
Advertisement
This happens a lot in std::vector. For instance, you could create a vector which has room for 16 elements but contains none. Then, the vector would contain 16 uninitialized elements, which would be initialized as the vector is resized or inserted into.
In standard C++ parlance, the Free Store is the region of memory that you manage using new and delete -- you're probably used to calling this “the heap”, but that's incorrect term, strictly speaking. It's called “free store” rather than “heap”, because the term “heap” is already used for standard library's algorithms related to heapsorting sequences.
Quote:Original post by Desperado
Second, he mentions this as a specific free store attribute. But isn't it a heap attribute too since you can allocate space at will and then call the constructor explicitly, which you can not do with new?

"free store" is the official C++ terminology for what are colloquially known as "heap objects," which are also object creating using the new operator.

There is no possible way, in the C++ language, to call a constructor explicitly. A constructor is not a function, it is not an entity that implements operator()() semantics. There are two ways to construct an object on the free store: using the new operator (as in Class* p = new Class();) or using ::operator new and the placement new operator (as in Class* p = ::operator new(sizeof(Class)); new (p) Class();)

In the latter case, it's possible to have storage allocated but no object yet constructed in that storage. This is in fact how std::vector does its magic.

Stephen M. Webb
Professional Free Software Developer

Quote:Original post by Bregma
... or using ::operator new and the placement new operator (as in Class* p = ::operator new(sizeof(Class)); new (p) Class();)

In the latter case, it's possible to have storage allocated but no object yet constructed in that storage. This is in fact how std::vector does its magic.


Does operator new only allocate memory or does it also create (uninitialized) objects? Or does placement new create the objects? Finally, does placement new call the constructor?
There's no difference between "allocating memory" and "creating uninitialized objects". The process of making an object on the freestore consists entirely of (1) allocating the memory, and (2) initializing the object by calling the constructor. operator new, called directly rather than through the new keyword, does only the former. Placement-new does only the latter.
Quote:Original post by Sneftel
There's no difference between "allocating memory" and "creating uninitialized objects". The process of making an object on the freestore consists entirely of (1) allocating the memory, and (2) initializing the object by calling the constructor. operator new, called directly rather than through the new keyword, does only the former. Placement-new does only the latter.


Very well, thank you. But since you can simulate this behaviour with malloc on the heap, why does he mention it as a specifical free store feature?
Quote:Original post by Desperado
Does operator new only allocate memory or does it also create (uninitialized) objects? Or does placement new create the objects? Finally, does placement new call the constructor?

::operator new only allocates memory. It is remarkably like std::malloc(), only it never returns a null pointer -- you would use ::operator new(nothrow) if you want that.

The only way to create an object is to run its constructor. ::operator new does not run any constructors, you do not get objects constructed into the memory returned by it. That's not the same as an uninitialized object. An uninitialized object has had its constructor run but the developer has not paid attention to class invariants and is probably going to be spending a lot of time debugging. Two completely different beasts.

Placement new creates an object on previously allocated memory. You can use std::malloc() to allocate memory and create an object in it using placement new, if you want.

One of the things placement new does is run the constructor. It also runs base class constructors and member constructors and adjusts the various pointers and vtables and whatever the runtime requires when an object is constructed.

Stephen M. Webb
Professional Free Software Developer

Quote:Original post by Desperado
But since you can simulate this behaviour with malloc on the heap
You'd better not. Memory managed with malloc/free cannot be mixed with memory managed with new/delete, and can have significant extra bookkeeping overhead. malloc and free are kept around for compatibility with C programs, but should not be used in C++.
Quote:There is no possible way, in the C++ language, to call a constructor explicitly.

Of course there is. How do you think containers are implemented?
It's called placement new. You demonstrated it yourself.

This topic is closed to new replies.

Advertisement