help-gplusplus
[Top][All Lists]
Advanced

[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'


reply via email to

[Prev in Thread] Current Thread [Next in Thread]