delete[] supplied a modified new-ed pointer. Undefined Behaviour?

时光毁灭记忆、已成空白 提交于 2019-12-01 18:16:59

问题


I saw some code as below during a peer-code-review session:

char *s = new char[3];
*s++ = 'a';
*s++ = 'b';
*s++='\0';
delete []s; // this may or may not crash on some or any day !!

Firstly, I know that in Standard C++, pointing to one-past the array-size is O.K. though accessing it results in undefined behaviour. So I believe the last line *s++='\0' is fine. But if I recall correctly, the C++ standard mandates that delete should be supplied the same pointer that new returned.

This I believe means that the returned pointer must not be tampered-with. I guess it is because new might keep some housekeeping info before the returned address that delete might use. Moving the new'd pointer might make this inaccessible.

Is it undefined behaviour or implementation-defined or unspecified? Can anyone confirm this please? Preferably by pointing to the correct place in the C++ Standard.

In the freely available draft version of the draft C++ Standard (Draft_SC22-N-4411.pdf) has the details in section 5.3.5. I got it from Bjarne's homepage.


回答1:


From the C++ Standard, section 5.3.5/2:

the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression. If not, the behaviour is undefined




回答2:


Yes, you must delete[] the original pointer you were given by new; in this case, that would be a pointer to the head of the array, rather than the tail. The code here is deleting some other unspecified random object.




回答3:


Yeah, recall how this is often implemented: new really calls malloc, which gives back a pointer to (void*)(&(((int*)p)[1])), where p is the actual start of the memory allocated, and the first int is the size of the actual memory we got back.

The pointer we get back is one sizeof(int) (or whatever alignment requires) further along in the actual memory allocated. We lay down our object there, leaving the actual size undisturbed.

Then when that pointer passed to delete, which passes it to free, free looks one int before the passed pointer, to find the size that's being given back.

Passing back something other than what we got is going to mean that free thinks an arbitrary amount of actual memory is being passed back, and it'll screw up the free list accordingly.

Again, this is how it's often implemented, not how new, delete, malloc, or free are required to be implemented.



来源:https://stackoverflow.com/questions/788482/delete-supplied-a-modified-new-ed-pointer-undefined-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!