Article View: comp.std.c++
Article #2525Re: Global Init/Shutdown: A solution (hopefully)
From: Fergus Henderson
Date: Sat, 11 Nov 1995 08:25
Date: Sat, 11 Nov 1995 08:25
79 lines
3164 bytes
3164 bytes
JdeBP@jba.co.uk writes:
>Further to the global initialisation/cleanup discussion, can anyone tell me
>when `woggle::~woggle' is called in the following program ? Is undefined
>behaviour invoked ?
>#include <stdlib.h>
>
>class woggle {
>public:
> char * p ;
> woggle() p(new(nothrow()) char) {}
> ~woggle() { char * q = p ; p = 0 ; delete q ; }
>} ;
>
>void *
>std::operator new ( size_t s, const std::nothrow & ) throw()
>{
> return malloc(s) ;
>}
As discussed here recently, `operator new' should be defined in the
global namespace, as specified by 3.7.3. Your program violates
17.3.3.1/1 "a program shall not extend the namespace `std'".
>void
>std::operator delete ( void * p ) throw()
>{
> static woggle w ;
> *w.p = ' ' ;
> free(p) ;
>}
Even if this were defined in the global namespace, there would
still be a problem. You didn't replace `operator new(size_t)', so
there is no guarantee that objects passed to your replacement for
`operator delete' will have been allocated with `malloc()'.
>int
>main ( int, char ** )
>{
> delete new(nothrow()) char ;
> return EXIT_SUCCESS ;
>}
If we ignore the two problem noted above, there is still at least
one more problem.
Lets see... there are no user-defined global objects or static members
with constructors, so after execution of the constructors for library
objects such as `cin' and `cout', execution begins in main().
First we execute `new(nothrow()) char', which invokes `operator new (1,
nothrow())', which returns the result of `malloc(1)'.
Then we execute `delete' on the resulting `char *' pointer,
which invokes your `operator delete(void *)'.
One entry to your `operator delete', the constructor for `static woggle w'
gets executed. This initializes `w.p' with `new (nothrow()) char',
which as before returns the result of `malloc(1)'.
Then the code
*w.p = ' ' ;
free(p) ;
is executed to complete the execution of `operator delete'.
Finally, on exit from main(), the desctructor for `w' will be called.
Oops, undefined behaviour:
~woggle() { char * q = p ; p = 0 ; delete q ; }
^^^^^
Here `w.p' has already been deallocated, so any attempt to even
just copy the invalidated pointer it is undefined behaviour.
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID:
<9531518.10407@mulga.cs.mu.OZ.AU>Path:
arc1-ca.pugleaf.net!in1.uu.net!bounce-backReferences:
<199511110341.UAA26529@ncar.ucar.EDU>Show Full Headers
Complete Article Headers
Approved: fjh@cs.mu.oz.au Date: 11 Nov 95 08:25:25 GMT From: fjh@munta.cs.mu.OZ.AU (Fergus Henderson) Message-ID: <9531518.10407@mulga.cs.mu.OZ.AU> Newsgroups: comp.std.c++ Organization: Computer Science, University of Melbourne, Australia Path: arc1-ca.pugleaf.net!in1.uu.net!bounce-back References: <199511110341.UAA26529@ncar.ucar.EDU> Subject: Re: Global Init/Shutdown: A solution (hopefully) X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMKReCOEDnX0m9pzZAQEsWwF/baaLzH3U2FbZZ0n0d4RnH9wnyOaJnVe8 uW1/T1Ew4Ym4MLj4jhXP6TIxha7EqiGP =GUw9