C
cusTom3
first post here, so be gentle
i am modding doom3. the doom3 engine is proprietary and compiled. we
get source to a dll loaded by the engine.
the engine gives me an instance of a class idAASFile which contains the
following definition:
class idAASFile {
// removed irrelevant code
protected:
idList<aasPortal_t> portals;
// removed irrelevant code
}
i would like to add an instance of aasPortal_t to this idList. i have
added this to the dll code:
aasPortal_t portal = portals.Alloc();
i get a failed debug assertion:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) down in dbgdel.cpp.
i have read everything i can find on this. seems like it is usually one
of a few problems...
trying to delete a pointer to memory on the heap twice or trying to
delete a pointer to memory not on the heap.
mixing release and debug versions of executables and libraries:
http://xml.apache.org/xalan-c/faq.html
if i do a release build of the dll the assertion no longer fails
because it isn't checked, but the engine still bombs with:
Unhandled exception at 0x7c901230 in DOOM3.exe: User breakpoint.
i experienced something similar to this earlier and read that it is
heap corruption, so that tells me that i should have listened to the
debug assertion and not tried to ignore it, as far as i can tell,
eliminating the release - debug build option
which leads me to think deleting something invalid...
it will be handy to browse down through Alloc i am sure:
/*
================
idList<type>::Alloc
Returns a reference to a new data element at the end of the list.
================
*/
template< class type >
ID_INLINE type &idList<type>::Alloc( void ) {
if ( !list ) {
Resize( granularity );
}
if ( num == size ) {
Resize( size +
granularity );
}
return list[ num++ ];
}
then down into Resize where it actually dies:
/*
================
idList<type>::Resize
Allocates memory for the amount of elements requested while keeping the
contents intact.
Contents are copied using their = operator so that data is correnctly
instantiated.
================
*/
template< class type >
ID_INLINE void idList<type>::Resize( int newsize ) {
type *temp;
int i;
assert( newsize >= 0 );
// free up the list if no data is being reserved
if ( newsize <= 0 ) {
Clear();
return;
}
if ( newsize == size ) {
// not changing the
size, so just exit
return;
}
temp = list;
size = newsize;
if ( size < num ) {
num = size;
}
// copy the old list into our new one
list = new type[ size ];
for( i = 0; i < num; i++ ) {
list[ i ] = temp[ i ];
}
// delete the old list if it exists
if ( temp ) {
delete[] temp;
}
}
and the definition of list for kicks:
class idList {
// removed irrelevant code
private:
type * list;
}
the call to delete[] temp is the problem. I have read also that this
can happen when you don't implement a copy constructor and operator =
correctly, but aasPortal_t doesn't contain any dynamically allocated
pointers:
// cluster portal
typedef struct aasPortal_s {
short areaNum;
short clusters[2];
short clusterAreaNum[2];
unsigned short maxAreaTravelTime;
} aasPortal_t;
i can declare and Resize the same type of variable if it all happens in
the dll no problem.
void TestLocalInstantiation() {
idList<aasPortal_t> portals;
portals.Resize( 10, 10 );
}
so if the same code works when it is all local why does it fail when i
get an instance from the engine and try to modify it?
i just read this:
So I have yet to find a good book that covers windows dll nuances in
c++, if the engine is loading my dll dynamically we have different
heaps? how would i tell if this is the case?
Please help
Thanks,
steve
i am modding doom3. the doom3 engine is proprietary and compiled. we
get source to a dll loaded by the engine.
the engine gives me an instance of a class idAASFile which contains the
following definition:
class idAASFile {
// removed irrelevant code
protected:
idList<aasPortal_t> portals;
// removed irrelevant code
}
i would like to add an instance of aasPortal_t to this idList. i have
added this to the dll code:
aasPortal_t portal = portals.Alloc();
i get a failed debug assertion:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) down in dbgdel.cpp.
i have read everything i can find on this. seems like it is usually one
of a few problems...
trying to delete a pointer to memory on the heap twice or trying to
delete a pointer to memory not on the heap.
mixing release and debug versions of executables and libraries:
http://xml.apache.org/xalan-c/faq.html
if i do a release build of the dll the assertion no longer fails
because it isn't checked, but the engine still bombs with:
Unhandled exception at 0x7c901230 in DOOM3.exe: User breakpoint.
i experienced something similar to this earlier and read that it is
heap corruption, so that tells me that i should have listened to the
debug assertion and not tried to ignore it, as far as i can tell,
eliminating the release - debug build option
which leads me to think deleting something invalid...
it will be handy to browse down through Alloc i am sure:
/*
================
idList<type>::Alloc
Returns a reference to a new data element at the end of the list.
================
*/
template< class type >
ID_INLINE type &idList<type>::Alloc( void ) {
if ( !list ) {
Resize( granularity );
}
if ( num == size ) {
Resize( size +
granularity );
}
return list[ num++ ];
}
then down into Resize where it actually dies:
/*
================
idList<type>::Resize
Allocates memory for the amount of elements requested while keeping the
contents intact.
Contents are copied using their = operator so that data is correnctly
instantiated.
================
*/
template< class type >
ID_INLINE void idList<type>::Resize( int newsize ) {
type *temp;
int i;
assert( newsize >= 0 );
// free up the list if no data is being reserved
if ( newsize <= 0 ) {
Clear();
return;
}
if ( newsize == size ) {
// not changing the
size, so just exit
return;
}
temp = list;
size = newsize;
if ( size < num ) {
num = size;
}
// copy the old list into our new one
list = new type[ size ];
for( i = 0; i < num; i++ ) {
list[ i ] = temp[ i ];
}
// delete the old list if it exists
if ( temp ) {
delete[] temp;
}
}
and the definition of list for kicks:
class idList {
// removed irrelevant code
private:
type * list;
}
the call to delete[] temp is the problem. I have read also that this
can happen when you don't implement a copy constructor and operator =
correctly, but aasPortal_t doesn't contain any dynamically allocated
pointers:
// cluster portal
typedef struct aasPortal_s {
short areaNum;
short clusters[2];
short clusterAreaNum[2];
unsigned short maxAreaTravelTime;
} aasPortal_t;
i can declare and Resize the same type of variable if it all happens in
the dll no problem.
void TestLocalInstantiation() {
idList<aasPortal_t> portals;
portals.Resize( 10, 10 );
}
so if the same code works when it is all local why does it fail when i
get an instance from the engine and try to modify it?
i just read this:
The most common explanation for the problem is that it appears when
doing 'new' + 'delete' and the memory is cleared twice then (which is
not a good idea), or the wrong address space is cleared when using DLL
(that has its own heap).
So I have yet to find a good book that covers windows dll nuances in
c++, if the engine is loading my dll dynamically we have different
heaps? how would i tell if this is the case?
Please help
Thanks,
steve