I am finding myself needing (more out of convenience and code cleanliness than necessity) a specific type of container class that isn't already a part of the standard library. Like vector, since my container is resizable, I want to have more memory available than is actually currently being used. std::vector has the current 'size' and also the 'capacity' to grow without reallocations. When vector has the memory reserved, the reserved memory isn't automatically constructed as that could have undesired side-effects, or simply just not be possible if the templated type didn't have a default constructor.
So I basically have everything already written out, except I'd like some clarity about explicitly calling the constructors and destructors.
For allocating memory, without calling the constructors in the memory, which of these are considered better practice/more-common:
unsigned char *memory = new unsigned char[num * sizeof(MyType)]; void *memory = ::operator new(num * sizeof(MyType));Is this the time and place to use malloc() and free()?
Should I store the pointer as void* or unsigned char*?
Why unsigned char* over char*?
If I access a void* using the subscript operator, will [n] access (n * sizeof(unsigned char)) or (n * sizeof(void*)) into that block of memory?
(I would assume sizeof(void*), but if void* is used for raw data access, I'd suspect people would want to increment a byte at a time)
Is this the correct way to manually call the constructor on raw memory?
new (&memory[atByte]) MyType(constructorArguments);
Is placement-new the only way?
Is this the correct way to destruct the object?
And I can turn around and reconstruct it (with placement new again) to reuse the memory location?
How am I supposed to free the raw memory? Just delete?
But I have to run through it and destructor all the objects that haven't been destructed yet, right?
But I can't destruct any objects that haven't been constructed yet, right?
Any other tips or traps to watch out for?