[ODE] Possible dArray Bug

Mark Wayland Mark Wayland" <mwayland at torus.com.au
Sat Aug 9 03:09:02 2003


Or, if you want to use C++ code, you can in-place copy-construct T
which is conceptually "cleaner":

#include <new.h>

void push (const T item)
{
  if (_size < _anum)  _size++; else _setSize (_size+1, sizeof(T)); // line 1
  new(((T*)_data)+_size-1) T(item); // line 2
}

Cheers,
Mark

----- Original Message -----
From: "Vadim Macagon" <vadim_mcagon@hotmail.com>
To: "ODE List" <ode@q12.org>
Sent: Saturday, August 09, 2003 5:08 PM
Subject: [ODE] Possible dArray Bug


> Hi,
>
> I started writing this email an hour or so before finding out that this
> issue had already come up... back on the 15 of July, and clearly hasn't
been
> addressed yet, I believe there are other patching still pending for the
> tri-collider. Is it because only Erwin deals with the tri-collider (and
he's
> away frolicking in some field somewhere)?
>
> --- and now the actual email:
>
> As you know I've been messing with the tri-collider for a few days and
> haven't noticed any major bugs that caused everything to crash, until
today.
> I don't exactly know why it turned up in this particular program (but not
in
> my other one).
> But anyway, in array.h you have this:
>
> void push (const T item) {
>   if (_size < _anum)  _size++; else _setSize (_size+1, sizeof(T)); // line
1
>   ((T*)_data)[_size-1] = item; // line 2
> }
>
> Let's say the array is empty, so _setSize() gets called, it allocates some
> raw memory (possibly junk filled). Now if T has a copy-assignment operator
> defined, and that copy-assignment operator happens to access some member
of
> T and that member contains junk, well bad things are going to happen.
That's
> what happens in line 2 above.
>
> Back to the tri-collider, when temporal coherence is enabled (lets say for
> spheres as an example) you have this happening:
>
> if (!sphereTC){
>   TriMesh->SphereTCCache.push(dxTriMesh::SphereTC());
>   ...
> }
>
> SphereTC is derived from OPCODE's SphereCache and SphereCache has a member
> of type Container, a Container has its own copy-assignment operator
defined
> which deletes a member array if that array has been allocated (the usual
"if
> array not null then delete" thing), except that array isn't null because
the
> Collider constructor (which would set it to null) was never called when
> dArray allocated the memory for the new SphereTC slot.
>
> My proposed solution is this:
>
> void push (const T item) {
>   if (_size < _anum)  _size++; else _setSize (_size+1, sizeof(T));
>   memcpy( &(((T*)_data)[_size-1]), &item, sizeof(T));
> }
>
> This way no assignment-copy operator will be called and the whole mess
> described above can be avoided.
>
> Patch attached.
>
> Cheers,
>
> Vadim.
>