# delete [] on different type than new

This topic is 2528 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

This is probably a stupid question. I came across a bug written below. It makes sense that new and delete need to be called for the same types, but I don't understand why this would fail since the memory layout is identical. Vector3f is just a POD so the destructor should be empty, no? I've verified there's no alignment issues, that is, the byte difference between pListOfFloat3s[1] - pListOfFloat3s[0] is indeed 12 bytes. There must be some additional info stored in the block header for user defined types. If anyone can be specific on why this crashes or can provide some documentation on what's happening, I'd sure appreciate it.
 /*** Largely simplified ***/ struct Vector3f { float x, y, z; }; int main() { Vector3f *pListOfFloat3s = new Vector3f[ 100 ]; float *pFloats = reinterpret_cast< float* >( pListOfFloat3s ); delete [] pFloats; // Crash Here. // delete [] pListOfFloat3s; // This succeeds when swapped with line above } 

##### Share on other sites
Rhetorical question: When calling delete[] on something, how does delete[] know how many variables are in the array that it's supposed to be freeing?

Answer: It hides the number of variables that are in the array, usually right before the array itself.

[color="#1c2837"]Vector3f *pListOfFloat3s = new Vector3f[ 100 ];
The above stores extra data telling how many variables are in the array. In this case, 100 instances of Vector3f.

float *pFloats = reinterpret_cast< float* >( pListOfFloat3s ); delete [] pFloats; // Crash Here.
How many floats are you passing for it to delete here? 300.
How many variables are you telling it to delete? 100.

I don't know if that's the cause of your crash, but it's certainly a problem of some kind.

##### Share on other sites
The above is invalid. If it compiles, the results are undefined (aka, compiler is free to do what it wants) behavior.

----------

sizeof(Vector3f) = 12 bytes. 100x = 1200 bytes (there's a slight possibility it could be different).
sizeof(float) = 4 bytes. 100x = 400 bytes.

The number of elements deleted is different, so if it did work, the guts of new/malloc would suddenly be missing 800 bytes of memory.

Internally, some compilers implement new[] like this: -4 p n*sizeof(T) [len ][..........]
Or, the number of elements is stored at -4 offset of the pointer you get. After all, delete[] needs to know how much memory to release.

But it can be tracked differently.

Since memory is usually stored in some form of interconnected list, after delete is called, it could look like this: -4 p [xxx][next_free][prev_free]Or anything else really. Obviously, if such delete[] were to remove 400 instead of 1200, these offsets could be wrong.

In short, since delete[] needs to know how much memory to release and since that information is kept internally by operator new, anything can happen. Even if sizeof(T) were identical, non-POD types would invoke destructor and that destructor would operate on invalid data.

Any discussion related to this is utterly futile, it's simply invalid and compiler will output code with undefined behavior. Not much to reason about.

##### Share on other sites

Any discussion related to this is utterly futile, it's simply invalid and compiler will output code with undefined behavior. Not much to reason about.
[/quote]

I wasn't intending on a large discussion. I just wanted to find out where my assumptions were wrong and these two posts have provided that. Thanks!

1. 1
2. 2
JoeJ
20
3. 3
frob
17
4. 4
5. 5

• 10
• 10
• 11
• 13
• 9
• ### Forum Statistics

• Total Topics
632197
• Total Posts
3004728

×

## Important Information

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!