Deleting an array in the wrong way

Possible duplicate:
How can pairing a new [] with deletion only lead to a memory leak?

I've always been told that it is not safe to call delete on an array allocated by the new []. You should always combine new with delete and new [] with delete [].

Therefore, I was surprised to find that the following code compiles and works fine, both in debug mode and in Release mode under VS2008.

class CBlah { public: CBlah() : m_i(0) {} private: int m_i; }; int _tmain(int argc, _TCHAR* argv[]) { for(;;) { CBlah * p = new CBlah[1000]; // with [] delete p; // no [] } return 0; } 

It took me a while to figure out why this even works, and I think it's just luck and undefined behavior.

BUT ... it made me wonder ... why doesn't Visual Studio pick it up, at least in the Debug memory manager? Is it because there is a lot of code that makes this error, and they don’t want to break it, or they don’t think that the task of the Debug memory manager is to catch this error?

Any thoughts? Is this a common abuse?

+4
source share
9 answers

It will probably compile ok because there is no information in the pointer (compilation time) that will see if the pointer points to an array or what. For instance:

 int* p; cin>>x; if(x == 0) p = new int; else p = new int [10]; delete p; //correct or not? :) 

Now about work in order. This is called undefined behavior in C ++, that is, there is no guarantee that it will happen - everything can work fine, you can get segfault, you can just get the wrong behavior, or your computer may decide to call 911. UB <=> no guarantee

+9
source

This behavior is undefined and everything is fair in love, war and undefined behavior ... :)

+3
source

According to MDSN, it translates delete to delete [] when trying to delete an array. (See there , for example). Although you should have a warning after compilation.

+1
source

The reason Debug Memory Manager does not perceive this error is probably because it is not implemented at the new / delete level, but at the level of the memory manager, which receives a new / delete call to allocate the required memory.
At this point, there is no difference between the new array and the scalar new.

+1
source

You can read these SO answers and links about delete and delete[] : About deleting, deleting a statement, deleting [], ...

0
source

I do not know what makes you think that "works fine." It compiles and exits without crashing. This does not mean that there was no leakage or damage to the heap. In addition, if you succeed this time, it will not necessarily make it safe.

Sometimes even rewriting a buffer is something that will get away with you because the bytes you wrote were not used (perhaps this is an addition for alignment). However, you should not do this.

By the way, the new T [1] is a form of the new [] and still requires the removal of [], although in this case there is only one element.

0
source

An interesting point. As soon as I looked through the code and tried to convince the programmers to fix the new [], remove the inconsistency. I argued myself as "Element 5" from Effective C ++ by Scott Meyers. However, they argued with the words: "What you want, it works well!" and proved that there was no memory leak. However, it only worked with POD types. It looks like MS is trying to fix the inconsistency, as indicated by Raveline.

What happens if you add a destructor?

 #include <iostream> class CBlah { static int instCnt; public: CBlah() : m_i(0) {++instCnt;} ~CBlah() { std::cout <<"d-tor on "<< instCnt <<" instance."<<std::endl; --instCnt; } private: int m_i; }; int CBlah::instCnt=0; int main() { //for(;;) { CBlah * p = new CBlah[10]; // with [] delete p; // no [] } return 0; } 

No matter how stupid the “intellect” correction is added to VS, the code is not portable.

0
source

Remember that “working correctly” is in the “undefined behavior” universe. It is possible that a specific version of a particular compiler implemented this so that it works in every sense and purpose. It is important to remember that this is not guaranteed , and you really cannot be sure that it works 100%, and you cannot know that it will work with the next version of the compiler. Nor is it portable, as another compiler may work differently.

0
source

This works because the particular C ++ runtime library it was associated with uses the same heap for operator new and operator new[] . Many do this, but some do not, so practice is not recommended.

Another big difference is that if CBlah had a nontrivial destructor, delete p; called it only for the first object in the array, while delete[] p; necessarily called it for all objects.

-1
source

All Articles