# Confusion about memory allocation and construction. (C++)

## Recommended Posts

CDProp    1451
I'm not quite sure what it means to "construct" an object. For instance, it is my understanding that if you use malloc() instead of new, it will allocate the memory without calling any constructors. Would it be illegal, then, to do something like this?
MyClass *p = (MyClass*)malloc( 8 * sizeof(MyClass) );
p[0].m_iMember = 5;

In this case, aren't I assigning to an unconstructed object? Why does it matter? Or doesn't it?

##### Share on other sites
Evil Steve    2017
Quote:
 Original post by CDPropI'm not quite sure what it means to "construct" an object.For instance, it is my understanding that if you use malloc() instead of new, it will allocate the memory without calling any constructors.
Correct.

Quote:
 Original post by CDPropWould it be illegal, then, to do something like this?MyClass *p = (MyClass*)malloc( 8 * sizeof(MyClass) );p[0].m_iMember = 5;In this case, aren't I assigning to an unconstructed object? Why does it matter? Or doesn't it?
I'm not sure about that, I think it's undefined behaviour. In practice, it'll work so long as m_iMember is a primitive type; if it's more complicated, like a std::string, then calling operator=() on it will probably break horribly.

Basically, constructing an object means calling the constructor for it. That will call the constructor for all member variables (Which does nothing for primitive types). For std::string for instance, the default constructor might set the string's length variable to 0, and the string's data pointer to null, or to point at an empty string. Operator=() would then release any memory associated with the string, allocate enough storage for the new string, and copy the contents.
If you allocated a std::string with malloc(), then tried to assign something to it, the default constructor wouldn't be called, meaning the size and data pointer will be gibberish, and would probably crash when the string tries to free it's current buffer (Which is gibberish) inside operator=() because it'd be deleting an invalid pointer.

Note: The above stuff is for illustration only, std::string might not really work like that.

##### Share on other sites
stonemetal    288
It rather depends. If MyClass is just data say:
class myclass{
public:
int a;
float b;
};

Then yeah it doesn't matter. If MyClass has virtual functions then any call to those functions will fail. Part of an object that isn't visible, yet still gets setup by the constructor is the V-table(virtual function table or some equivalent data structure) where functions are looked up when you make a call to a virtual function.

##### Share on other sites
CDProp    1451
Oh, ok, I see. Thanks!

So if I wanted to be safe and make sure that all of those objects were constructed, would it be sufficient to do something like this?
for(int i = 0; i < 8; i++)    p[i] = MyClass();

Intuitively, it seems this would only construct a temporary object and then assign it to the memory I allocated, but it's the only thing I can think of off the top of my head.

##### Share on other sites
nobodynews    3126
Quote:
 Original post by CDPropOh, ok, I see. Thanks!So if I wanted to be safe and make sure that all of those objects were constructed, would it be sufficient to do something like this?for(int i = 0; i < 8; i++) p[i] = MyClass();Intuitively, it seems this would only construct a temporary object and then assign it to the memory I allocated, but it's the only thing I can think of off the top of my head.

No, if you have a random block of memory and you want to construct an object at a location in that block then you will probably want to look at 'placement new'.

The question is: why you would want to do this? It can be useful, but there is probably an alternative.

Zahlman    1682