operator delete[] woes

operator delete[] woes

Post by Macs 4 Sal » Sat, 24 Jul 2004 12:49:03


Hi All -

I have a rather *** problem regarding operator delete[] and CW 9.2.
Calling delete[] on an object that was allocated with new[] but is then
POINTED to by the object's superclass results in only 1 virtual dtor
being called. This is a little tricky to explain, so maybe a simple
test program will clarify:

#include <iostream>
using namespace std;

class foo
{
public:
virtual ~foo() { cout << "foo dtor\n"; }
};

class bar : public foo
{
public:
virtual ~bar() { cout << "bar dtor\n"; }
};

int main()
{
using namespace std;

// This first example results in expected behavior.
// The delete operator calls bar's dtor, which then in turn
// calls foo's dtor.
foo *f = new bar;
delete( f );

cout << "--------\n";

// Again, expected behavior.
// The delete[] operator calls bar's dtor, which then in turn
// calls foo's dtor.
bar *b = new bar[1];
delete [] b;

cout << "--------\n";

// Badness!
// The delete[] operator does not call bar's dtor. Instead,
// the CW compiler always uses foo's dtor when calling
// __destroy_new_array. Can this be fixed?
foo *foobar = new bar[1];
delete [] foobar;

return 0;
}

Sample output:

bar dtor
foo dtor
-------
bar dtor
foo dtor
-------
foo dtor

In the above example, regular new/delete work as expected -- both dtors
are called as expected. But new[]/delete[] only works if the CW
compiler KNOWS it's delete[]'ing an object of type "bar". Otherwise,
foo's dtor is mistakenly called. A quick disassembly of the code
revealed that the CW compiler is passing __destroy_new_array a pointer
to foo's dtor. I cannot figure out a way to make the compiler know to
use bar's dtor (like with using regular new/delete).

I kind of blundered into this problem while tracking down some other
memory leaks. Needless to say, I was shocked to find my app leaking a
LOT of memory. Unfortunately, this is a Mac port of a 500,000 line
MSVC++ program, and I can't easily re-engineer the codebase without
making massive changes. BTW, trying this test code on MSVC++ results in
expected behavior -- delete[] always calls bar's dtor on my PC. I guess
that's why the original PC program didn't leak memory so much;-)

Anyway, any help y'all can give would be appreciated. TIA.

- phil
 
 
 

operator delete[] woes

Post by Phil Sula » Sat, 24 Jul 2004 12:58:04

Sorry, but I accidentally posted my message using the wrong "author
name". No, I'm not trying to sell any of my Macs. Yes, I'm having a
problem with CW's delete[] operator and need help to stop my program
from leaking memory:-)

Thanks!

- phil
( XXXX@XXXXX.COM ; NOT XXXX@XXXXX.COM )

 
 
 

operator delete[] woes

Post by David Phil » Sat, 24 Jul 2004 15:27:10

In article <220720042248323653% XXXX@XXXXX.COM >,


...
...

Wow! if class bar is ever modified to contain any members, then:

class bar : public foo
{
int mBar;
public:
virtual ~bar() { cout << "bar dtor\n"; }
};

foo *foobar = new bar[2];

fooBar[1] will reference into the middle of some object. (foobar is of
type foo*, but it is really pointing to an array of larger bars, so any
pointer arithmetic on foo will fail to align with the underlying
objects.)

If your program is really doing this, it sounds like a serious problem
that must be fixed immediately.

(Although, I do admit that the case of allocating an array length 1 (or
zero) is a special case that won't cause a problem.)
 
 
 

operator delete[] woes

Post by Matthew Co » Sat, 24 Jul 2004 19:12:59

In article <220720042248323653% XXXX@XXXXX.COM >,



Don't Do That. The C++ Standard says of delete[] that "if the dynamic
type of the object to be deleted differs from its static type, the
behavior is undefined" (5.3.4p3). More accessibly, Item 3 of Meyers
"More Effective C++" explains why you should "Never treat arrays
polymorphically".

Best wishes,
Matthew Collett

--
Those who assert that the mathematical sciences have nothing to say
about the good or the beautiful are mistaken. -- Aristotle
 
 
 

operator delete[] woes

Post by Phil Sula » Sat, 24 Jul 2004 23:49:06

In article < XXXX@XXXXX.COM >, David



You're right, but luckily the code I'm working with doesn't have that
problem (phew!). I think the original PC coders did casts as necessary
before doing any sort of pointer arithmetic. If they hadn't, my code
would be crashing six ways from Sunday:-)

BTW, casting foobar to a (Bar *) before calling delete[] does fix my
leak problem. But due to the huge number of subclasses I'm dealing
with, I unfortunately can't resort to doing that:-(

- phil
 
 
 

operator delete[] woes

Post by Howard Hin » Sat, 24 Jul 2004 23:52:31

In article < XXXX@XXXXX.COM >,




<nod> The easiest way to convert this into a conforming program on CW
9.2 (well, at least one of the easiest ways) is to:

std::vector<std::tr1::shared_ptr<foo> > foobar(1,
std::tr1::shared_ptr<foo>(new bar));

-Howard
 
 
 

operator delete[] woes

Post by Phil Sula » Sat, 24 Jul 2004 23:57:35

In article < XXXX@XXXXX.COM >, Matthew



Ahh, if only it were that easy:-) Unfortunately, this problem is
althroughout the code and prevents me from easily re-engineering the
program. I'm really hoping for a "nice" way to fix this problem (ie,
by using RTTI, a CW pragma, etc). As I mentioned in my previous post,
casting foobar to a (bar *) does work, but unfortunately I can't easily
add casts to the code due to the numerous different subclassees that
need to be delete[]'d and the way they're managed in memory.

Differences between MSVC++ and CW are the WORST things to have to deal
with when porting code:-(

- phil
 
 
 

operator delete[] woes

Post by Miro Juris » Sun, 25 Jul 2004 03:07:56

In article <230720040957042494% XXXX@XXXXX.COM >,



Actually, the worst thing are incompetent windows programmers. The second worst
is the compiler.

The issue you raise here is a bug in their code and the right answer it to beat
them on the head with a stick until they fix it.

meeroh

--
If this message helped you, consider buying an item
from my wish list: < http://www.yqcomputer.com/ ;
 
 
 

operator delete[] woes

Post by Phil Sula » Sun, 25 Jul 2004 03:19:58

In article < XXXX@XXXXX.COM >,



LOL!

Thanks meeroh -- I needed a good laugh after dealing with this
problem:-)

- phil
 
 
 

operator delete[] woes

Post by Phil Sula » Sun, 25 Jul 2004 03:23:04

In article
< XXXX@XXXXX.COM >, Howard



Very interesting -- thanks! I may give this a try as an experiment,
but given the way the PC guys allocate objects in their original code
(via some rather *** macros), this may not be the best solution for
me:-(

- phil
 
 
 

operator delete[] woes

Post by froeth » Sun, 25 Jul 2004 04:49:25


You are missing the point here: The code is defective and needs
fixing. You are very lucky it does not (always) crash with VC. And the
programmer who wrote that code really needs to learn C++ programming
before he/she continues to do any more C++ hacking. Everything else is
a disaster waiting to happen.

Thorsten
 
 
 

operator delete[] woes

Post by Wade Willi » Wed, 28 Jul 2004 03:05:44

In article <230720040957042494% XXXX@XXXXX.COM >, Phil Sulak



In 99% of the cases I've found, CW is right. Make the PC developers
change their code to meet the standard.

Wade
 
 
 

operator delete[] woes

Post by Wade Willi » Wed, 28 Jul 2004 03:07:29

In article <260720041305444930% XXXX@XXXXX.COM >, Wade




Whoops I just remembered where you work. :)

Never mind. :)

Wade