Jump to content
  • Advertisement
Sign in to follow this  
999999999

C++ classes modifying their members

This topic is 4866 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I have spent all the day on this problem but it seems that I can't find a solution to it: I have a class to handle the fire particle fx. This is a piece:
class JPFXFire
{
public:
	JPFXFire(J3DDevice *_device);
	~JPFXFire();

	void SetRadius(float r);


	void Create(); // called when all fire parameters have been passed
	void Render();
	void Release();
private:
	J3DDevice *device;
	JVector position; // fire position
	float radius; // fire radius
};

JPFXFire::JPFXFire(J3DDevice *_device)
{
  device = _device;

  <dump the address of 'device' to file>
}

void JPFXFire::SetRadius(float r) { radius = r; }

void JPFXFire::Create()
{
<dump the address of 'device' to file>

<use the device> [error]
}

// class initialization
JPFXFire *pFire = new JPFXFire(device); // device=valid pointer to a 3D device
pFire->SetRadius(fireRadius);
<other parameter settings>
pFire->Create();


The first dump gives me an address (the same I passed with new()) The second dump shows a different address! How did the class change it??? [Edited by - 999999999 on July 22, 2005 4:37:55 PM]

Share this post


Link to post
Share on other sites
Advertisement
You're probably overwriting the bounds of an array. Put a debugger watchpoint on the memory location of the "device" variable and see where it fires.

Share this post


Link to post
Share on other sites
I tried with the debugger. The wrong address even points to a location outside the bounds of my RAM, but I knew it. The problem is: Why does it happen?
I have found out that the address gets probably changed immediately after the constructor because I have made 'device' public and from outside the class I dumped it and it had changed immediately after the constructor call;

JPFXFire *pFire = new JPFXFire(device); (during the construction I got the right address)
DUMP--> wrong address

Share this post


Link to post
Share on other sites
Quote:
Original post by 999999999
I tried with the debugger. The wrong address even points to a location outside the bounds of my RAM, but I knew it. The problem is: Why does it happen?


Again, you're probably overwriting the bounds of the array. The problem isn't within your class from what we can see, it's probably from someplace else in your code, caused by a line something like this:

int foo[10];
foo[20] = 3;

Share this post


Link to post
Share on other sites
I had already thought about that and I looked in my code but there aren't instructions. The point is that the "change" happens between the constructor and the next call.

JPFXFire::JPFXFire(J3DDevice *_device)
{
this->device = _device;
DUMP(this->device); // address assigned correctly
}

DUMP(pFire->device); // wrong address



I mean, there are no other instructions between the new() call and the second dump.
I use this kind of system with lots of classes and it's the first time I encounter such problems.
If I add
void JPFXFire::Create(J3DDevice *_device)
{
this->device = _device;
}
then the pointer is OK and it remains OK forever. But what happens in the meantime that modifies the pointer?

[Edited by - 999999999 on July 22, 2005 4:36:49 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by 999999999
I mean, there are no other instructions between the new() call and the second dump.


That's now what you originally showed. You're saying your code now looks like this:
class JPFXFire
{
private:
J3DDevice * device;
public:
JPFXFire( J3DDevice * _device );
void DumpDevice();
...
};

JPFXFire::JPFXFire( J3DDevice * _device )
{
device = _device;
...
DUMP( device );
}
void JPFXFire::DumpDevice ()
{
DUMP( device );
}

void UsingCode( void )
{
JPFXDevice * device = ....;
JPFXFire * fire = new JPFXFire( device ); //causes one DUMP right before returning
fire->DumpDevice(); //causes another dump immediately
}

Correct?

If this is truely your situation and it is failing, there are few possible reasons:
1) You have a buggy DUMP function, post it's source.
2) Your code is partially misbuilt or stale, do a full rebuild.
3) If UsingCode is a member function of a class, and you assign (or otherwise access) any memembers, it's possible that the "this" pointer is corrupt - any assignments will be overwriting random memory, and any pointers will in turn point randomly into memory, using them will similarly give random results and writing to those addresses overwrite existing memory locations.
4) Your compiler is on crack.
5) JPFXFire's constructor has a local class with a destructor that is buggy and overwriting device

IMO the most likely problems are one of these two:
1) You've got stale object files. Solution: Do a full rebuild.
2) You're excluding some of the code shown to us and you are not in fact doing two immediate consecutive dumps like you think/say you are. Solution: Show us more code (as in, don't sumarize, copy & paste & do not cut)

Share this post


Link to post
Share on other sites
DUMP() is only a macro. It is like this:

FILE *fp = fopen("device_dump.txt","a");
fprintf(fp,"%lu",device);
fclose(fp);

not very good but it has always given the expected results


It seems that everything I do in the constructor gets (canceled) when the construction finishes. Very strange: if e.g. I put in the constructor
radius = 123.4f;
the debugger (during the Create() call) shows a misterious '0' for radius.
Why did he ignore the constructor instruction? Why did I get a '0' and not a random value in the memory? It's late, time to sleep. Tomorrow I'll look more deeply through the code; I'd like to post more sources, but I feel I would complicate things, as in those files there is much code not connected with this.

Share this post


Link to post
Share on other sites
I have tried adding another particle fx, now I have got a list of pointers I allocate with new(). The problem remains for each class in the list. the very same problem, so I think it is not something like an allocation outside array bounds (I have checked disabling most engine parts). It looks like the constructor does non have effect, at least not on the class it belongs to.
For example, I have a 4D vector as a member of the JPFXFire class, that vector class has a constructor that sets the w component to 1.0f. I suppose the constructors of the member classes is called within the constructor of the main class, right? But with the debugger I noticed that w is 0.0f!!! Please, help me. I don't know what to do and I must continue programming the engine!

Share this post


Link to post
Share on other sites
This is really driving me crazy. I removed the pointer assignment from the constructor, having it only in Create() and it worked for what was in create(), but in the render() function the device was invalid again! This means that the line this->device = _parameter_device; has no permanent effect in Create() too, but it used to have! Then I tried putting the pointer assignment also in the constructor and this time everything I do in the constructor remain! But still not in Create(), where the device is invalid! I don't really understand this, so I'll post some more code.



// structure for particle fx (used also by the world editor and saved to file
typedef struct JEditor_ParticleFX
{
char name[64]; // the particle fx virtual name in the game
void *pPFX; // generic pointer to the particle fx object (used only in the game) [need to be cast]
JPFXType type; // the particle fx type
JVector position; // particle fx position
JMatrix matrix; // object transformation matrix [only in the editor]
int iParams[16]; // integer effect parameters
float fParams[16]; // float effect parameters

JEditor_ParticleFX()
{
pPFX = NULL;
memset(name,0,sizeof(name));
matrix.Identity();
// memset(iParams,0,sizeof(int)*16);
// memset(fParams,0,sizeof(float)*16);
}
~JEditor_ParticleFX()
{
if (pPFX)
delete pPFX;
pPFX = NULL;
}
} JEditor_ParticleFX;

// I have an object manager, which keeps STL vectors of different object: for what concern particle fx:

//ObjectManager.h

class JObjMGR {
//.................................//
private:
vector <JEditor_ParticleFX *> gamePFX;
};
//ObjectManager.cpp

void JObjMGR::Add(JEditor_ParticleFX *pfx) {
gamePFX.push_back(pfx);
}

void JObjMGR::SetupAfterAddingObjects() {
// particle fx setup operations
vector <JEditor_ParticleFX *>::iterator _p = gamePFX.begin();
while (_p != gamePFX.end()) // loop through each game particle fx
{
switch ((*_p)->type) // allocate memory for the appropriate particle fx structure and fill it with particle fx data
{
case JPFXType_Fire:
(*_p)->pPFX = new JPFXFire(device); // allocate memory
((JPFXFire *)(*_p))->SetPosition((*_p)->position); // copy the particle fx position
((JPFXFire *)(*_p))->SetRadius((*_p)->fParams[JPFX_FIRE_F_RADIUS]); // copy the fire radius
JTexture *pFlame; // fire textures pointers
game->GetPFXFireTextures(&pFlame); // get fire textures pointers
((JPFXFire *)(*_p))->SetTextures(pFlame); // set fire textures pointers
((JPFXFire *)(*_p))->Create(device); // create the fire
break;
}

_p++;
}
}

// I used to load JEditor_ParticleFX structures from file but I hard-coded two particle fx removing the file-loading operations (it didn't change anything)

// Called before SetupAfterAddingObjects():

JEditor_ParticleFX *pfx = new JEditor_ParticleFX;
pfx->matrix.Identity();
strcpy(pfx->name,"_try");
pfx->type = JPFXType_Fire;
pfx->position = JVector(6.8f,514.9f,201.0f);
pfx->fParams[0] = 1.0f;
pfx->pPFX = NULL;
objMGR->Add(pfx);
JEditor_ParticleFX *pfx2 = new JEditor_ParticleFX;
pfx2->matrix.Identity();
strcpy(pfx2->name,"_try2");
pfx2->type = JPFXType_Fire;
pfx2->position = JVector(-30.3f,518.4f,342.2f);
pfx2->fParams[0] = 2.0f;
pfx2->pPFX = NULL;
objMGR->Add(pfx2);



Hope this clarifies things better.

Share this post


Link to post
Share on other sites
Try deleting intermediate files and rebuild the project. To do that in MSDEV, use Clean Solution in Build menu. My suggestion would also be that you check your other code because the one you currently listed here looks perfectly OK, so the problem might lie somewhere else.
Exclude the code you listed here and try running without it. If you run into problems similar to current ones, the problem is outside listed code.

Good luck.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!