I have tried some interesting code(at least for me !). Here it is.
#include <iostream>
struct myStruct{
int one;
/*Destructor: Program crashes if the below code uncommented*/
/*
~myStruct(){
std::cout<<"des\n";
}
*/
};
struct finalStruct {
int noOfChars;
int noOfStructs;
union {
myStruct *structPtr;
char *charPtr;
}U;
};
int main(){
finalStruct obj;
obj.noOfChars = 2;
obj.noOfStructs = 1;
int bytesToAllocate = sizeof(char)*obj.noOfChars
+ sizeof(myStruct)*obj.noOfStructs;
obj.U.charPtr = new char[bytesToAllocate];
/*Now both the pointers charPtr and structPtr points to same location*/
delete []obj.U.structPtr;
}
I have allocated memory to charPtr and deleted with structPtr. It is crashing when I add a destructor to myStruct otherwise no issues.
What exactly happens here. As I know delete[] will call the destructor as many times as number given in new[]. Why it is not crashing when there is no destructor in myStruct?
This is a common memory management mistake. Once you call delete with a pointer, your program no longer has the right to use the memory the pointer points to.
Pointers to unions? Like structures, we can have pointers to unions and can access members using the arrow operator (->).
Deleting a pointer does not destruct a pointer actually, just the memory occupied is given back to the OS. You can access it untill the memory is used for another variable, or otherwise manipulated. So it is good practice to set a pointer to NULL (0) after deleting.
delete keyword in C++Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression.
First off, storing one member of a union and then reading another in the way you're doing it is Undefined Behaviour, plain and simple. It's just wrong and anything could happen.
That aside, it's quite likely the type pun you're attempting with the union actually works (but remember it's not guaranteed). If that's the case, the following happens:
You allocate an array of bytesToAllocate
objects of type char
and store the address in the unionised pointer.
Then, you call delete[]
on the unionised pointer typed as myStruct*
. Which means that it assumes it's an array of myStruct
objects, and it will invoke the destructor on each of these objects. However, the array does not contain any myStruct
objects, it contains char
objects. In fact, the size in bytes of the array is not even a multiple of the size of myStruct
! The delete
implementation must be thoroughly confused. It probably interprets the first sizeof(myStruct)
bytes as one myStruct
object and calls the destructor in those bytes. Then, there's less than sizeof(myStruct)
bytes left, but there are still some left, so the destructor is called on those incomplete bytes, reaches beyond the array, and hilarity ensues.
Of course, since this is just UB, my guess at the behaviour above could be way off. Plain and simple, you've confused it, so it acts confused.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With