Reputation: 35982
struct Rational
{
int a;
int b;
};
struct NextOnFreeList
{
NextOnFreeList *next;
};
// Build the linked-list
NextOnFreeList* freeList = NULL; // head of the linked-list
size_t size = (sizeof(Rational) > sizeof(NextOnFreeList *)) ? sizeof(Rational) : sizeof(NextOnFreeList *);
NextOnFreeList *runner = static_cast <NextOnFreeList *> new char [size]; // LineA
freeList = runner;
for (int i = 0; i < EXPANSION_SIZE; i++) {
runner->next = static_cast <NextOnFreeList *> new char [size];
runner = runner->next;
}
runner->next = 0;
Question 1> LineA Since the size of Rational(i.e. 8 bytes) is larger than NextOnFreeList(i.e. 4 bytes), each element in the Linked-list will ONLY use partial of the allocated memory. Is that correct?
// Delete the linked-list
NextOnFreeList *nextPtr = NULL;
for (nextPtr = freeList; nextPtr != NULL; nextPtr = freeList) {
freeList = freeList->next;
delete [] nextPtr; // LineB
}
Question 2> LineB why should we use 'delete [] nextPtr' instead of 'delete nextPtr'?
Question 3>
Rational* ptr = static_cast<Rational*>( freeList ); // LineC
ptr->a = 10;
ptr->b = 20;
Is it true by LineC, we can bring back all the allocated memory original with size of 'size' and use the memory to store all elements inside the Rational.
Upvotes: 0
Views: 102
Reputation: 3338
Q1: Yes, but I would rather use std::allocator<Rational>::allocate
(or union
of both - you will avoid alignment problems this way)
Q2: It is actually bad, because you should cast it to char*
first, then use delete[]
. Again, using std::allocator
would be better. And: It does not matter on default implementation (calls free
), but forget I said that ;) ... using malloc
/free
directly is safer.
Q3:: It is fine, but I am not sure if static_cast
will allow that (reinterpret_cast
or casting to void*
in between may help)
EDIT: I hope your Q3 is not final, because you need to update the free list first (before using the pointer).
2nd EDIT: Links + note: hiding the free-list inside the allocator would be best for C++ (using malloc
/free
directly in it, or new[]
/ delete[]
)
Upvotes: 2
Reputation: 4948
Q.1:
Yes but that is not the best idea to use static_cast
. reinterpret_cast
would be more preferable.
Q.2:
I dont there is a defined behavior to recognize your static_cast
to accept a simple delete
. safest way would be to look at this as the original allocation of array. So cast back to char*
and use []delete
Q.3 yep, yes you can.
Upvotes: 0
Reputation: 96251
char*
so you must delete it as such (by casting back to char*
and then delete[]
) or you have undefined behavior.reinterpret_cast
you would be violating the strict aliasing rules, again causing undefined behavior.Upvotes: 0