Topic: delete and delete[] are error prone
Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1996/10/22 Raw View
Mike Harrold wrote:
>
> Steve Clamage (clamage@taumet.eng.sun.com) wrote:
> : In article 7f40dbcd@philipg, "Philip Gruebele" <philipg@bayarea.net> writes:
> : >Does the standard say specify what happens if you use the wrong delete
> : >operator. For example, if I used "delete" to delete an array or vice
> : >versa? Microsoft Visual C++ simply says that the behaviour is undefined.
>
> : That is correct. Behavior is undefined.
[...]
> : "Undefined behavior" means, among other things, that an implementation
> : is allowed to detect the error. You can always ask your favorite
> : vendor to provide such checks.
>
> : Requiring such checks all the time of all implementations was judged
> : too expensive, particularly since other, equally serious, errors are
> : allowed to go undetected, such as writing outside the bounds of allocated
> : memory, deleting an object twice, deleting an invalid address.
>
> : It certainly makes sense to allow optional checking for all these and
> : other memory management errors. The effect on performance of always
> : doing the checks is dramatic, however, which is why it is not required.
Even the user can provide some checking by replacing global new,
new[], delete, delete[].
A simple way to do that is to have two global var:
map<void*, bool> ptr_set, array_set;
// the bool is true if memory has not been deleted
Custom operator new:
- call malloc or built-in operator new
- add the ptr to ptr_set with value true; if it's already there remove
the previous one
Custom operator new[]:
- call malloc or built-in operator new[]
- add the ptr to array_set with value true; if it's already there
remove the previous one
Custom operator delete (void* ptr) check if ptr is in ptr_set:
- if it is:
- if the associated value is true then
set it to false
built-in operator delete ptr or free
- else
FatalError ("memory deleted twice with delete")
- if not:
- if ptr is in array_set then
FatalError ("delete used instead of delete[]")
- else
FatalError ("delete used on memory never allocated"
"with new or new[]")
Custom operator delete [] (void* ptr) check if ptr is in array_set:
- if it is:
- if the associated value is true then
set it to false
built-in operator delete[] ptr or free
- else
FatalError ("memory deleted twice with delete[]")
- if not:
- if ptr is in ptr_set then
FatalError ("delete[] used instead of delete")
- else
FatalError ("delete[] used on memory never allocated"
" with new or new[]")
FatalError (str) print str and abort or perhaps throw str.
I would prefer to abort since if we are deleting invalid ptr it means
that something really bad is going on and our data is probably
corrupted.
You should also check if ptr is 0 in delete before searching in xxx_set.
> In addition, with the g++ implementation of new/delete (and I suspect it
> is probably not alone in this), new[] calls new and delete[] calls delete.
> The array versions are just wrappers. The two function calls are basically
> identical.
Yes and no; even if everything finnaly call operator new or malloc,
the wrong address can be passed because the address return by new[] is
not always the one returned by operator new[].
You can really trash the heap if you mix new/new[]/malloc and
delete/delete[]/free; it might work with one implementation or appear
or to work in a particular situation, and break after.
The effect of a debugging heap will be to slow downyour program, but
with a map or something like that I don't thing the slowdown will be
'dramatic'. On the other hand, checking all array bound (as many
Pascal compiler propose) have a dramatic effect on perfomance (and
code size) (as I have mesured with TurboPascal).
--
Valentin Bonnard
mailto:bonnardv@pratique.fr
http://www.pratique.fr/~bonnardv (Informations sur le C++ en Francais)
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Nico Josuttis <nico@bredex.de>
Date: 1996/10/22 Raw View
In article <53o5af$e7e@news1.infinet.com>, Mike Harrold <ao@infinet.com> wrote:
>Steve Clamage (clamage@taumet.eng.sun.com) wrote:
>: In article 7f40dbcd@philipg, "Philip Gruebele" <philipg@bayarea.net> writes:
>: >Does the standard say specify what happens if you use the wrong delete
>: >operator. For example, if I used "delete" to delete an array or vice
>: >versa? Microsoft Visual C++ simply says that the behaviour is undefined.
>
>: That is correct. Behavior is undefined.
>
> ...
>
>In addition, with the g++ implementation of new/delete (and I suspect it
>is probably not alone in this), new[] calls new and delete[] calls delete.
>The array versions are just wrappers. The two function calls are basically
>identical.
>
>/Mike
BE CAREFUL, that does NOT mean, new and new[] or delete and delete[]
are always the same even NOT for g++ !!!
You can overload them (global or for individual classes) and then
there are differences. Libraries do that, programmers do that, class
implementors do that!
So check that you always call the right delete.
The real problem is that compilers can't detect the difference between
a pointer to one element and an array of elements by type checking.
This is the price for being backward compatible to C.
--
Nico address: BREDEX GmbH, Nicolai Josuttis
email: nico@bredex.de Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: dtaylor@pifus.com (David Taylor)
Date: 1996/10/23 Raw View
>In article <53o5af$e7e@news1.infinet.com>, Mike Harrold <ao@infinet.com> wrote:
>>
>>In addition, with the g++ implementation of new/delete (and I suspect it
>>is probably not alone in this), new[] calls new and delete[] calls delete.
>>The array versions are just wrappers. The two function calls are basically
>>identical.
>>
I don't see how they can simply be wrappers, otherwise the destructors of the
items in the array would not get called. See Scott Meyers "More Effective
C++" for info on delete[] and operator delete[]. In effect operator
delete[](void*) could just be a wrapper around operator delete(void*), but the
code generated from "delete[] pointer" would be quite different from "delete
pointer".
Dave
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: sean@delta.com (Sean L. Palmer)
Date: 1996/10/23 Raw View
> The effect of a debugging heap will be to slow downyour program, but
> with a map or something like that I don't thing the slowdown will be
> 'dramatic'. On the other hand, checking all array bound (as many
> Pascal compiler propose) have a dramatic effect on perfomance (and
> code size) (as I have mesured with TurboPascal).
But a debugging switch to implement these checks is a very handy thing
to track down 'stupidity' errors. Many compilers provide a sort of
add-in package that integrates with the compiler to provide these
checks, even now. Like Borland's CodeGuard.
Of course you wouldn't ever want to SHIP a version compiled this way...
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: "Philip Gruebele" <philipg@bayarea.net>
Date: 1996/10/10 Raw View
Does the standard say specify what happens if you use the wrong delete
operator. For example, if I used "delete" to delete an array or vice
versa? Microsoft Visual C++ simply says that the behaviour is undefined.
It seems to me that there needs to be some static or run-time checking for
whether or not the correct operator is used. Otherwise hidden bugs could
be introduced if the wrong delete operator is used.
Regards
Philip Gruebele
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: clamage@taumet.eng.sun.com (Steve Clamage)
Date: 1996/10/11 Raw View
In article 7f40dbcd@philipg, "Philip Gruebele" <philipg@bayarea.net> writes:
>Does the standard say specify what happens if you use the wrong delete
>operator. For example, if I used "delete" to delete an array or vice
>versa? Microsoft Visual C++ simply says that the behaviour is undefined.
That is correct. Behavior is undefined.
>It seems to me that there needs to be some static or run-time checking for
>whether or not the correct operator is used. Otherwise hidden bugs could
>be introduced if the wrong delete operator is used.
"Undefined behavior" means, among other things, that an implementation
is allowed to detect the error. You can always ask your favorite
vendor to provide such checks.
Requiring such checks all the time of all implementations was judged
too expensive, particularly since other, equally serious, errors are
allowed to go undetected, such as writing outside the bounds of allocated
memory, deleting an object twice, deleting an invalid address.
It certainly makes sense to allow optional checking for all these and
other memory management errors. The effect on performance of always
doing the checks is dramatic, however, which is why it is not required.
---
Steve Clamage, stephen.clamage@eng.sun.com
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: ao@infinet.com (Mike Harrold)
Date: 1996/10/14 Raw View
Steve Clamage (clamage@taumet.eng.sun.com) wrote:
: In article 7f40dbcd@philipg, "Philip Gruebele" <philipg@bayarea.net> writes:
: >Does the standard say specify what happens if you use the wrong delete
: >operator. For example, if I used "delete" to delete an array or vice
: >versa? Microsoft Visual C++ simply says that the behaviour is undefined.
: That is correct. Behavior is undefined.
: >It seems to me that there needs to be some static or run-time checking for
: >whether or not the correct operator is used. Otherwise hidden bugs could
: >be introduced if the wrong delete operator is used.
: "Undefined behavior" means, among other things, that an implementation
: is allowed to detect the error. You can always ask your favorite
: vendor to provide such checks.
: Requiring such checks all the time of all implementations was judged
: too expensive, particularly since other, equally serious, errors are
: allowed to go undetected, such as writing outside the bounds of allocated
: memory, deleting an object twice, deleting an invalid address.
: It certainly makes sense to allow optional checking for all these and
: other memory management errors. The effect on performance of always
: doing the checks is dramatic, however, which is why it is not required.
In addition, with the g++ implementation of new/delete (and I suspect it
is probably not alone in this), new[] calls new and delete[] calls delete.
The array versions are just wrappers. The two function calls are basically
identical.
/Mike
--
+--------------------------------------------------------------------------+
| Take the cheese to sickbay, the Doctor should take a look at it as soon |
| as possible. -- B'lanna Torres - Star Trek Voyager - 'Learning Curve'. |
+--------------------------------------------------------------------------+
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]