new/delete problem | developer.brewmp.com new/delete problem | developer.brewmp.com

Developer

new/delete problem

Forums:

I've got a couple of classes, a parent class and a child class. Simplified, they look like this:
class Entity
{
[INDENT]int a;[/INDENT]
;

class EnemySub : public Entity
{
[INDENT]int xVel;
int yVel;
[/INDENT]
;

Later, I've got a function:
foo()
{
[INDENT]Entity* ptrEntity;
ptrEntity = new EnemySub;
delete ptrEntity;// this line causes an error

[/INDENT]

When I run foo() above, I get the following error in MSVC6's debug window:
HEAP[BREW_Emulator.exe]: Invalid Address specified to RtlFreeHeap( 2f0000, 2f894c )

However, if I typecast the pointer, it works fine:
bar()
{
[INDENT]Entity* ptrEntity;
ptrEntity = new EnemySub;
delete (EnemySub*)ptrEntity;// no error now

[/INDENT]

I first noticed this when using a function which gets the pointer of the entity from a list, and, strangely enough, the value I was storing was different depending on whether or not I typecast the result to an Entity* or an EnemySub*. In other words...

Entity* ptr1;
Entity* ptr2;
ptr1 = (Entity*)GetFirstEntity();
ptr2 = (EnemySub*)GetFirstEntity();
assert(ptr1==ptr2);// FAILS
Why would the values of the pointer be different based on what I'm pointing to? :confused:
new/delete just call MALLOC and FREE, using the code that I've seen many people on this forum using.

Any help anyone could offer would be greatly appreciated!!

Ok, I've done a little more research, and here's what I've found...
If I create a new object of the base class type, the pointer gets initialized to the same value that FREE returns. In other words,
Entity* ptrEntity1;
Entity* ptrEntity2;
ptrEntity1 = new Entity;
ptrEntity2 = new EnemySub;
When I set a breakpoint and go into the new calls, and check the value that FREE returns, ptrEntity1 gets set to the same value. However, ptrEntity2 gets a value 4 bytes ahead. In those bytes, it wrote the value x94009501. I'm guessing that this is how it knows which object type this pointer points to, so when I call a virtual function, it knows which one to call. However, when I test this in just a standard c++ program (win32 console app), it doesn't do this.
Does this mean that I need up upgrade my new and delete functions, so that they know what memory address to free when I try to free an address that's not at the beginning of a memory block? Anybody have any insight on this at all?
Thanks!!

Ok, I've done a little more research, and here's what I've found...
If I create a new object of the base class type, the pointer gets initialized to the same value that FREE returns. In other words,
Entity* ptrEntity1;
Entity* ptrEntity2;
ptrEntity1 = new Entity;
ptrEntity2 = new EnemySub;
When I set a breakpoint and go into the new calls, and check the value that FREE returns, ptrEntity1 gets set to the same value. However, ptrEntity2 gets a value 4 bytes ahead. In those bytes, it wrote the value x94009501. I'm guessing that this is how it knows which object type this pointer points to, so when I call a virtual function, it knows which one to call. However, when I test this in just a standard c++ program (win32 console app), it doesn't do this.
Does this mean that I need up upgrade my new and delete functions, so that they know what memory address to free when I try to free an address that's not at the beginning of a memory block? Anybody have any insight on this at all?
Thanks!!

Hi Kartan,
have you overloaded new and delete operator at class level? or with global scope? i will recommend overloading to global scope so that all allocation and deallocation can be handled.
Regards,
Ali

Hi Kartan,
have you overloaded new and delete operator at class level? or with global scope? i will recommend overloading to global scope so that all allocation and deallocation can be handled.
Regards,
Ali

You need to either cast back to the derived class or have a virtual destructor. FWIW, this is standard C++ behavior and not specific to BREW.
If there are no destructors or virtual functions involved and you have RTTI disabled, you could probably get away with it.

You need to either cast back to the derived class or have a virtual destructor. FWIW, this is standard C++ behavior and not specific to BREW.
If there are no destructors or virtual functions involved and you have RTTI disabled, you could probably get away with it.