Objects in Memory
This is a matter of understand how memory works for objects in C++
Lets imagine we have the following object:
class SimpleObject
{
public:
char name[16];
int age;
};
It's size will be 20. (In most platforms). So in memory it will look like this:
Bytes
name age
0000000000000000|0000|
You can change memory manually so you could create the object by doing something like:
//Manual assigment
staticMemory[0] = 'F';
staticMemory[1] = 'e';
staticMemory[2] = 'l';
staticMemory[3] = 0;
int* age = reinterpret_cast<int*>(&staticMemory[16]);
*age = 21;
You can prove object is successfully created by doing something like:
printf("In static manual memory the name is %s %d years old\n",
reinterpret_cast<SimpleObject*>(staticMemory)->name
,reinterpret_cast<SimpleObject*>(staticMemory)->age);
Which outputs:
In static manual memory the name is Fel 21 years old
By obvious practical reasons this is not used in real life, but it helps understand how objects are storage.
New operator
New operator basically works as this:
- Allocate the size of the object in bytes in the heap memory
- Call the object constructor to fill the memory
It's more complicated depending on the implementation, but the idea is the same.
So if the constructor is:
SimpleObject::SimpleObject(const char* name,int age)
{
memcpy(this->name,name,16);
this->age = age;
}
This code:
SimpleObject* dynamicObject = new SimpleObject("Charles",31);
Will be almost equivalent to:
SimpleObject* dynamicMemoryObject = (SimpleObject*)malloc( sizeof(SimpleObject) );
memcpy(dynamicMemoryObject->name,"Charles",16);
dynamicMemoryObject->age = 31;
As I said is a little bit more complicated than that, but the idea is the same.
Replacing an object in memory
Now that this is understood there are many ways to replace an object in the same memory space, the most common way is placement new. Many examples below:
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <new>
class SimpleObject
{
public:
char name[16];
int age;
SimpleObject(const char* name,int age);
SimpleObject()
{
}
};
SimpleObject::SimpleObject(const char* name,int age)
{
memcpy(this->name,name,16);
this->age = age;
}
//Object in static memory
SimpleObject staticObject;
//20 bytes in static memory
char staticMemory[20];
int main()
{
//Manual assigment
staticMemory[0] = 'F';
staticMemory[1] = 'e';
staticMemory[2] = 'l';
staticMemory[3] = 0;
int* age = reinterpret_cast<int*>(&staticMemory[16]);
*age = 21;
printf("In static manual memory the name is %s %d years old\n",
reinterpret_cast<SimpleObject*>(staticMemory)->name
,reinterpret_cast<SimpleObject*>(staticMemory)->age);
//Static object
new (&staticObject) SimpleObject("John",23);
printf("In static object the name is %s\n",staticObject.name);
//Static memory
SimpleObject* staticMemoryObject = reinterpret_cast<SimpleObject*>(staticMemory);
new (staticMemoryObject) SimpleObject("Jenny",21);
printf("In static memory the name is %s\n",staticMemoryObject->name);
//Dynamic memory (heap)
void* dynamicMemoryObject = malloc( sizeof(SimpleObject) );
new (dynamicMemoryObject) SimpleObject("Xavier",22);
printf("In dynamic memory the name is %s\n",reinterpret_cast<SimpleObject*>(dynamicMemoryObject)->name);
free(dynamicMemoryObject);
//Dynamic object
SimpleObject* dynamicObject = new SimpleObject("Charles",31);
printf("In a dynamic object the name is %s\n",dynamicObject->name);
printf("Pointer of dynamic object is %8X\n",dynamicObject);
//Replacing a dynamic object with placement new
new (dynamicObject) SimpleObject("Charly",31);
printf("New name of dynamic object is %s\n",dynamicObject->name);
printf("Pointer of dynamic object is %8X\n",dynamicObject);
//Replacing a dynamic object with stack object
SimpleObject stackObject("Charl",31);
memcpy(dynamicObject,&stackObject,sizeof(SimpleObject));
printf("New name of dynamic object is %s\n",dynamicObject->name);
printf("Pointer of dynamic object is %8X\n",dynamicObject);
//Replacing a dynamic object with a new allocation
dynamicObject = new SimpleObject("Sandy",22);
printf("New name of dynamic object is %s\n",dynamicObject->name);
printf("Pointer of dynamic object is %8X\n",dynamicObject);
return 0;
}
With output:
In static manual memory the name is Fel 21 years old
In static object the name is John
In static memory the name is Jenny
In dynamic memory the name is Xavier
In a dynamic object the name is Charles
Pointer of dynamic object is 4F8CF8
New name of dynamic object is Charly
Pointer of dynamic object is 4F8CF8
New name of dynamic object is Charl
Pointer of dynamic object is 4F8CF8
New name of dynamic object is Sandy
Pointer of dynamic object is FD850