Prev: Converting new [] to vectors
Next: Operator chaining
From: Andrew on 28 Feb 2010 11:50 I am familiar with the need to match new[] to delete[]. It is a programming error to say new[] then say delet without the square brackets. In some environments this can lead to heap corruption, as Meyers warns in item 5 of Effective C++. What I am looking for is chapter in verse in the std that says this is wrong, along with something that clearly explains why this error can cause heap corruption. This is not for me - I already know not to do it. But there is a colleague that needs convincing. I have to use his code in the library of his that I need. It is trashing the heap and I know the code does new[] but delete without the brackets. He wont change the offending code without proof that its current form can cause heap corruption. I did try telling him that common heap mgmt code will coalesce adjacent free blocks when doing a delete and that such a mismatch can cause this to go wrong but he wont take my word for it. I dont think he will take Meyers word for it either. Regards, Andrew Marlow -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Gert-Jan de Vos on 28 Feb 2010 20:36 On Mar 1, 5:50 am, Andrew <marlow.and...(a)googlemail.com> wrote: > I am familiar with the need to match new[] to delete[]. It is a > programming error to say new[] then say delete without the square > brackets. In some environments this can lead to heap corruption, as > Meyers warns in item 5 of Effective C++. > > What I am looking for is chapter in verse in the std that says this is > wrong, along with something that clearly explains why this error can > cause heap corruption. 5.3.5-2 [expr.delete]: "... In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub- object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined. ..." 1.3.12 [defns.undefined]: "behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements. Undefined behavior may also be expected when this International Standard omits the description of any explicit definition of behavior. [Note: permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. ]" In practice: an implementation needs to store information about the length of the array somewhere in the heap block. In any case, delete will call just one destructor, while delete[] will call the destructor of all objects in the array. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Tony Delroy on 28 Feb 2010 20:36 On Mar 1, 1:50 pm, Andrew <marlow.and...(a)googlemail.com> wrote: > I am familiar with the need to match new[] to delete[]. It is a > programming error to say new[] then say delet without the square > brackets. In some environments this can lead to heap corruption, as > Meyers warns in item 5 of Effective C++. > > What I am looking for is chapter in verse in the std that says this is > wrong, along with something that clearly explains why this error can > cause heap corruption. This is not for me - I already know not to do > it. But there is a colleague that needs convincing. I have to use his > code in the library of his that I need. It is trashing the heap and I > know the code does new[] but delete without the brackets. He wont > change the offending code without proof that its current form can > cause heap corruption. > > I did try telling him that common heap mgmt code will coalesce > adjacent free blocks when doing a delete and that such a mismatch can > cause this to go wrong but he wont take my word for it. I dont think > he will take Meyers word for it either. >From 5.3.5 [expr.delete], point 2: "In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object created by a new- expression, or a pointer to a sub-object (_intro.object_) representing a base class of such an object (_class.derived_). If not, the behav- ior is undefined. In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression.18) If not, the behavior is unde- fined. [Note: this means that the syntax of the delete- expression must match the type of the object allocated by new, not the syntax of the new-expression. ]" It might also help this guy to read the FAQ 16.12 onwards.... Cheers, Tony -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Seungbeom Kim on 28 Feb 2010 20:35 Andrew wrote: > I am familiar with the need to match new[] to delete[]. It is a > programming error to say new[] then say delet without the square > brackets. In some environments this can lead to heap corruption, as > Meyers warns in item 5 of Effective C++. > > What I am looking for is chapter in verse in the std that says this is > wrong, along with something that clearly explains why this error can > cause heap corruption. This is not for me - I already know not to do > it. But there is a colleague that needs convincing. I have to use his > code in the library of his that I need. It is trashing the heap and I > know the code does new[] but delete without the brackets. He wont > change the offending code without proof that its current form can > cause heap corruption. > > I did try telling him that common heap mgmt code will coalesce > adjacent free blocks when doing a delete and that such a mismatch can > cause this to go wrong but he wont take my word for it. I dont think > he will take Meyers word for it either. 5.3.5[expr.delete]/2 says (where I added line breaks): "In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression. If not, the behavior is undefined. [Note: this means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new- expression. ]" -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Alf P. Steinbach on 28 Feb 2010 20:35
* Andrew: > I am familiar with the need to match new[] to delete[]. It is a > programming error to say new[] then say delet without the square > brackets. In some environments this can lead to heap corruption, as > Meyers warns in item 5 of Effective C++. > > What I am looking for is chapter in verse in the std that says this is > wrong, along with something that clearly explains why this error can > cause heap corruption. This is not for me - I already know not to do > it. But there is a colleague that needs convincing. I have to use his > code in the library of his that I need. It is trashing the heap and I > know the code does new[] but delete without the brackets. He wont > change the offending code without proof that its current form can > cause heap corruption. > > I did try telling him that common heap mgmt code will coalesce > adjacent free blocks when doing a delete and that such a mismatch can > cause this to go wrong but he wont take my word for it. I dont think > he will take Meyers word for it either. Oh dear. Well, in the standard it's �5.3.5/2, "shall" and "If not, the behavior is undefined", and also at a lower level, for the allocation and deallocation functions called by the operator expressions, �3.7.3.2/3. But your colleague may perhaps need to understand why. I guess he understands that for an array of non-POD object using plain 'delete' may cause a resource leak, since it will at best only call the destructor of the first object. But what can go wrong for an array of POD element type? Well, for non-POD element type 'new[]' has to associate the pointer with the number of elements in the array, which might be fewer than there's room for in the allocated block. And one way of doing that is to store the logical array size at the start of the allocated block and return a pointer to somewhere after that. Then delete[] can look back a bit to find the info. And in a simple implementation new[] may not differentiate between POD and non-POD element type, meaning that it'll do the same for POD element type, even though the info is not needed there. Then using plain 'delete' for deallocation will pass an incorrect pointer to the deallocation function, namely not a pointer to the allocated block but a pointer somewhat offset from the start of that block, and goodbye. Cheers & hth., - Alf -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |