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.

+2


a source to share


6 answers


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.

+1


a source


The amount of memory freed is undefined - your code is illegal in C ++.



+9


a source


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 ...

+5


a source


Don't worry, the amount of memory to be removed is written inside the allocated memory block header, so your code won't skip over anything and remove exactly what was allocated. But the above won't be true if you allocate it as an array.

+1


a source


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.)

0


a source


Agree with alemjerus - this does not create a memory leak. My two cents: sizeof (int) + sizeof (char) may not equal sizeof (Foo) due to the filling of structure elements, so the size of the allocated / freed memory block is equal to sizeof (Foo).

0


a source







All Articles