I'm trying to make my own memory allocator in C++ for educational purposes, and I have a code like this:
class IntObj
{
public:
IntObj(): var_int(6) {}
void setVar(int var)
{
var_int = var;
}
int getVar()
{
return var_int;
}
virtual size_t getMemorySize()
{
return sizeof(*this);
}
int a = 8;
~IntObj()
{}
private:
int var_int;
};
And I'm stuck with how to have unused memory chunks merge. I'm trying to test it like this:
char *pz = new char[sizeof(IntObj) * 2]; //In MacOS, IntObj takes 16 bytes
char *pz2 = &pz[sizeof(IntObj)]; // Take address of 16-th cell
char *pz3 = new char[sizeof(IntObj) / 2]; //Array of 8 bytes
char **pzz = &pz2;
pzz[sizeof(IntObj)] = pz3; // Set address of cell 16 to the pz3 array
new (&pzz) IntObj; //placement new
IntObj *ss = reinterpret_cast<IntObj *>(&pzz);
cout << ss->a;
The output is 8 as expected. My questions:
- Why the output is correct?
- Is the code like this correct? If not, are there any other ways to implement coalescence of two memory chunks?
UPDATE: All methods work correctly. e.g this would work:
ss->setVar(54);
cout << ss->getVar();
The output is 54.
UPDATE 2: First of all, my task is not to request a new memory block from OS for instantiating an object, but to give it from a linked list of free blocks(that were allocated when starting a program). My problem is that I can have polymorphic objects with different sizes, and don't know how to split memory blocks, or merge (that is what I understand by merging or coalescing chunks) them (if allocation is requested) effectively.
There's a number of misunderstandings apparent here
pzzis a pointer that is pointing to only a singlechar*, which is the variablepz2. Meaning that any access or modification pastpzz[0]is undefined behavior (very bad). You're likely modifying the contents of some other variable.This is constructing an
IntObjin the space of the variablepzz, not wherepzzis pointing to. The constructor of course setsato8thereby stomping on the contents ofpzz(it won't be pointing topz2anymore). I'm uncertain if this in-and-of-itself is undefined behavior (since there would be room for a wholeIntObj), but using it certainly is:This violates the strict-aliasing rule. While the standard is generous for
char*aliases, it does not allowchar**toIntObj*aliases. This exhibits more undefined behavior.If your question comes down to whether or not you can use two independent and contiguous blocks of memory as a single block then no, you cannot.