Dynamically distributed structure and molding
Let's say I have a first structure like this:
typedef struct {
int ivalue;
char cvalue;
}
Foo;
And the second one:
typedef struct {
int ivalue;
char cvalue;
unsigned char some_data_block[0xFF];
}
Bar;
Now let's say that I am doing the following:
Foo *pfoo;
Bar *pbar;
pbar = new Bar;
pfoo = (Foo *)pbar;
delete pfoo;
Now when I call the delete operator, how much memory does it free?
sizeof(int) + sizeof(char)
or
sizeof(int) + sizeof(char) + sizeof(char) * 0xFF
?
And if this is the first case due to casting, is there a way to prevent memory leaks?
Note: please do not answer "use C ++ polymorphism" or similar, I am using this method for some reason.
a source to share
The whole idea behind such code is just undefined behavior. Do not do this. What happens if someone would overload operator new
and operator delete
for one structure rather than another?
The only legal way to do what you want is to inherit both structures from the comon base with virtual destructors - then you will have some defined behavior and no deallocation problems.
However, if operator new
they are operator delete
not overloaded, and both structures have trivial destructors, they can simply work on your implementation - the compiler will call ::operator delete()
, which has one parameter - the address of the block, and it will be free in exactly the right amount of memory. However, don't count on it - your code does have undefined behavior.
a source to share
There probably won't be any guarantee on your machine, as with most implementations delete
(when freeing memory), it doesn't matter what type of pointer is, but the address. Because of this, it will probably free the memory allocated for Bar (in this case).
However, remove the view as an extension, for example:
if ( ptr != 0 ){
ptr->~ClassName();
operator delete(ptr);
}
Consider the case where you are passing in the wrong type delete
. The wrong destructor is being called, which will not result in a compile-time error, but may cause a run-time problem.
Consider the case where new and deleted operators are overloaded ...
a source to share
Aside from linguistic law issues, your code, in practice, will do the right thing and free the entire object. Most compilers will simply refer to the underlying malloc / free (or similar) when calling new / delete.
However, it does matter if you have a non-trivial destructor in Bar
. The absence of a virtual destructor means that only the destructor of the base class is called when deleted using a base class pointer.
IIRC, failure to call a derived destructor is the only caveat with the above code. Other than that, I believe this is valid code. (My C ++ is rusty these days, so I might be off the mark.)
a source to share