[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: g++ 3.4.1 core dump with -O2
From: |
Ralf Fassel |
Subject: |
Re: g++ 3.4.1 core dump with -O2 |
Date: |
Wed, 14 Jul 2004 11:13:21 +0200 |
User-agent: |
Gnus/5.1006 (Gnus v5.10.6) XEmacs/21.4 (Security Through Obscurity, linux) |
* Guy Harrison <swamp-DEL-dog@ntlworld.com>
| > We have a nasty coredump which occurs at all optimization level -O --
| > -O3, but is not present at -O0/-g. It happens when our code executes
| > new foo*[0]
| ^^^
| That's okay. C++ ought to receive a unique pointer for each new[0] and
| consequently you must delete[] it.
That's what we do. The code in question is some ancient version of an
ancestor of std::vector<>. It is part of the main library of our
system and is used by all of our programs in a test suite of ~250
tests. But only one program crashes. Makes me nuts not to be able to
find the cause... The one program in question does nothing
extra-ordinary, but I think I will re-check all the components it
uses.
| Now the rusty bit. I think c99 disallows such a pointer. That's to
| say whereas malloc(0) may well return a unique pointer whose value
| could formally be passed around (and subsequently free()'d), c99
| disallows the value in the pointer itself...
My malloc(3) manpage says:
When called with size of zero, malloc returns a valid pointer to
a block of zero bytes. Storage into a block of length zero will
corrupt the malloc arena and may have serious consequences.
So malloc(0) should be ok unless the pointer is actually used (in
which case I would have expected an error by the dmalloc package).
There is no warning in the manpage about not passing this pointer to
free() (it explicitely says `valid pointer' above).
| Check you don't have any ?alloc calls in your own code which might
| be suspect due to above.
Guess I will run dmalloc again with the malloc(0) warning enabled.
| Code snippet if possible?
template <class type>
class xxx
{
...
int length( int newlen )
{
std::cerr << "a1d:: " << (void*)this << " length/1, oldlen "
<< len << " newlen " << newlen << std::endl;
* type **nv = new type* [newlen];
std::cerr << "a1d:: new DONE " << (void*)this << std::endl;
REQUIRE( nv, "a1dC - out of memory" );
int i = MIN(len,newlen);
std::cerr << "a1d:: " << (void*)this << " length-2, pt " << (void*) nv << "
i " << i << std::endl;
while( i-- )
{ nv[i] = v[i]; }
for( i=len; i<newlen; i++ )
{ nv[i] = new type; }
for( i=newlen; i<len; i++ )
{ delete v[i]; }
delete [] v;
v = nv;
return len = newlen;
}
The line marked * crashes when called with newlen(0) the nth time (and
only when the whole package is compiled with -O[1-3]). As you can
see, this is poor mans vector<>.resize(). We're currently in the
process of upgrading the compiler version, and wanted to change as
little as possible. Of course, we should use some std::container
here, get rid of the REQUIRE, etc etc, but...
I guess I will try whether
... = new type* [newlen ? newlen : 1];
makes any difference, too.
Thanks for the input.
R'