Skip to main content
gamedev.net
🔒 Locked

Pointer Question

Started by TSCrusader 34 replies 4.7k views
Original Post
TSCrusader
TSCrusader
I have a problem with the pointers in my project. When i compile the project using "Debug" Settings everything works fine, but when i compile it using "Release" it crashes with an access violation at the following line: v1.pos.x = m->Vertices[curr_offset_vertex + vertidx].Vec[0] * 0.015625f; Could you tell me where the problem could be or what i should post so that you can find the problem?
SiCrane
SiCrane
The most likely cause is that you're using an unitialized variable somewhere.
rip-off
rip-off
Could be quite a few things:
// in general, inside a member function of an invalid object?// I.e. the "this" pointer is bad?m->Vertices //  NUll/uninitialised/delete'd pointer?m->Vertices[curr_offset_vertex + vertidx] //  out of array bounds?.Vec[0]  // empty array/std::vector ?


If you are using vectors change the [ index ] to .at( index ), vectors throw exceptions when out of bounds, so that could rule out of bounds out as the problem...
TSCrusader
TSCrusader
maybe i should add that this line is in a class that was used as a normal variable before, but i tried to use it as a pointer now.
So this line is in
void MD3Model::RenderItp(int currframe, int nextframe, float pct)
Before i changed it, this class was used as following:
MD3Model lower, upper, head;
Now i use it as following:
MD3Model *lower, *upper, *head;
(very hard to explain in english, any germans here?) :)
rip-off
rip-off
Quote:
Original post by TSCrusader
maybe i should add that this line is in a class that was used as a normal variable before, but i tried to use it as a pointer now.
So this line is in
void MD3Model::RenderItp(int currframe, int nextframe, float pct)
Before i changed it, this class was used as following:
MD3Model lower, upper, head;
Now i use it as following:
MD3Model *lower, *upper, *head;


Chances are you are not saying

lower = new MD3Model(/*constuctor arguments*/);upper = new MD3Model(/*constuctor arguments*/);head  = new MD3Model(/*constuctor arguments*/);


That's assuming it was working before you changed it...
TSCrusader
TSCrusader
yeah thought so too, but i have done that.

Additionally i have a md3character (thats the class using the 3 md3models), that creates these md3models and can render them without errors.
But when i make a new md3character and give the addresses of these 3 md3models to it, the render crashes as i said above.
rip-off
rip-off
Quote:
Original post by TSCrusader
yeah thought so too, but i have done that.

Additionally i have a md3character (thats the class using the 3 md3models), that creates these md3models and can render them without errors.
But when i make a new md3character and give the addresses of these 3 md3models to it, the render crashes as i said above.


Do you mean like so

MD3Model m(/*ctor*/);

MD3Character c( &m ); // ?

Because that wont work...


Post your code.
Downer
Downer
Since your using pointsers rather then -> to get to variables, which seem public you could, * ...

ie ( *m ).Vertices[curr_offset_vertex + vertidx].Vec[0] * 0.015625f;

this way rather then following thru the pointer you are saying resolve the address and use the object it points too, they basically do the same thing but I remember hearing one of my profs mention they go about it differently.

Also if the 3 md3models were created by a md3character class they might be gone if you had deleted the origonal md3character. When you create them I assume they are created in a function and returned from teh class. If you have it returning pointers then you didnt actually return the 3 md3model classes just pointers to them and they would be considered part of the md3character class. If this is the case then you would have to return the md3model class rather then the pointer to it, and have pointers reference it after its been returned. Hoping its this simple for you to fix, it just being a scope issue.

Good luck, I will keep checking in, hope my bits help out ... Downer
rip-off
rip-off
Quote:

Since your using pointsers rather then -> to get to variables, which seem public you could, * ...

ie ( *m ).Vertices[curr_offset_vertex + vertidx].Vec[0] * 0.015625f;


They are idenitcal.
TSCrusader
TSCrusader
heres some of the code:

MD3Character cha;Md3Character *player;	cha.Initialize(d3d.pdevice);	cha.LoadPlayer("klesk\\","red");		player = new MD3Character();	player->Initialize(d3d.pdevice);	player->SetPlayer("klesk\\",cha.lower, cha.upper, cha.head);


here are the loadplayer and setplayer functions:

void MD3Character::LoadPlayer(char *path, char *skin){	char l_mpath[1024], u_mpath[1024], h_mpath[1024];	// model (lower, upper, head)	char l_spath[1024], u_spath[1024], h_spath[1024];	// skin	char a_path[1024];									// animation	sprintf(l_mpath, "%s\\lower.md3", path);	sprintf(u_mpath, "%s\\upper.md3", path);	sprintf(h_mpath, "%s\\head.md3", path);	sprintf(l_spath, "%s\\lower_%s.skin", path, skin);	sprintf(u_spath, "%s\\upper_%s.skin", path, skin);	sprintf(h_spath, "%s\\head_%s.skin", path, skin);	sprintf(a_path, "%s\\animation.cfg", path);	lower = new MD3Model();	upper = new MD3Model();	head = new MD3Model();	// Load Model	lower->LoadModel(l_mpath);	// lower body	upper->LoadModel(u_mpath);	// upper body	head->LoadModel(h_mpath);	// head	lower->Initialize(device);	upper->Initialize(device);	head->Initialize(device);	// Load Skins	lower->LoadSkin(l_spath, path);	upper->LoadSkin(u_spath, path);	head->LoadSkin(h_spath, path);	LoadAnim(a_path);	lower->LinkModel("tag_torso", upper);	upper->LinkModel("tag_head", head);	SetAnimation(LEGS_IDLE);	SetAnimation(TORSO_STAND);	Rotation.x = 0;	Rotation.y = 0;	Rotation.z = 0;	Initialized = true;}void MD3Character::SetPlayer(char *path, MD3Model *lower, MD3Model *upper, MD3Model *head){	char a_path[1024];		sprintf(a_path, "%s\\animation.cfg", path);	this->lower = lower;	this->upper = upper;	this->head = head;	LoadAnim(a_path);	//lower->LinkModel("tag_torso", upper);	//upper->LinkModel("tag_head", head);	SetAnimation(LEGS_IDLE);	SetAnimation(TORSO_STAND);	Rotation.x = 0;	Rotation.y = 0;	Rotation.z = 0;	Initialized = true;}


As you can see i am trying to load a model once and then use it for all the characters...
discman1028
discman1028
Not that this solves the problem, but might be good to know...

Debug mode clears all memory to 0 on startup, where Release mode leaves the memory uninitialized (as expected for a simple line like "int a;"). So that's at least why you get different results in the two modes.

--== discman1028 ==--
rip-off
rip-off
void MD3Character::LoadPlayer(char *path, char *skin){	char l_mpath[1024], u_mpath[1024], h_mpath[1024];	// model (lower, upper, head)	char l_spath[1024], u_spath[1024], h_spath[1024];	// skin	char a_path[1024];									// animation	sprintf(l_mpath, "%s\\lower.md3", path);	sprintf(u_mpath, "%s\\upper.md3", path);	sprintf(h_mpath, "%s\\head.md3", path);	sprintf(l_spath, "%s\\lower_%s.skin", path, skin);	sprintf(u_spath, "%s\\upper_%s.skin", path, skin);	sprintf(h_spath, "%s\\head_%s.skin", path, skin);	sprintf(a_path, "%s\\animation.cfg", path);        // and it goes on!


Ye Gods man, use std::string. Its more fun that way.

But other than that, Does your Character's class destructor destroy the Models inside it.

If it does, think about the effect of having "MD3Character cha;" go out of scope while you are still using pointers to things it has deleted.
TSCrusader
TSCrusader
@ discman1028: thx thats good to know :)

@ rip-pff:
It does not destroy the models and i only destroy it at the end of the program.

You should consinder that debug mode works fine.
TSCrusader
TSCrusader
I dont know if that could be the problem but i found out that when i debug in "release" mode and then press F11 on the following line
lower->SetInfo(l_currframe, l_nextframe, l_fps*(l_currtime - l_oldtime));
it should jump into this function and debug there, but it jumps over this function. Any ideas on that?

hmm tested that out with an messagebox and this messagebox is shown and then also the debugger jumps into this function...
Downer
Downer
it is a scope problem like I said, just before Rip-of ripped into me ... and while they do the same thing they way the compiler goes about doing it is slightly different thats all I said.

I then stated it prolly scope. you have a function void MD3Character::LoadPlayer(char *path, char *skin)
in this function the 3 models are create lower, upper, head all get newed thats fine .. thing is they lost scopre once that function is dead. what need to do is have the models pointers waiting before the call and passed in as variables. void MD3Character::LoadPlayer(char *path, char *skin, model* lower, model* upper, model* head )
this way when your done doing the new, its puts it in the ones that have a greater scope. If you then have your entire game ran from inside a single clss having the 3 model*'s as part of that class will keep them for the duration. ... Sorry if my msg doesnt come accross well ... Im practically falling asleep ... TSCrusader has anyquestions he can se the messaging service to ask and will get a direct answer with in no longer then 2 days
TSCrusader
TSCrusader
Im not sure if i understood that so i am going to ask :)

So i have to make a Md3Model array for example in my game class and pass the pointers of 3 of these models to the loadplayer function so that this function can fill these pointers? where should the "new Md3Model()" be then? And how can i pass pointers that can be modified?

[Edited by - TSCrusader on February 14, 2006 3:05:25 AM]
Enigma
Enigma
Quote:
Original post by Downer
it is a scope problem like I said, just before Rip-of ripped into me ... and while they do the same thing they way the compiler goes about doing it is slightly different thats all I said.

And you were wrong:
Quote:
C++ Standard, Final Draft, Section 5.2.5, Paragraph 3
If E1 has the type "pointer to class X," then the expression E1->E2 is converted to the equivalent form (*(E1)).E2;...

Quote:
I then stated it prolly scope. you have a function void MD3Character::LoadPlayer(char *path, char *skin)
in this function the 3 models are create lower, upper, head all get newed thats fine .. thing is they lost scopre once that function is dead. what need to do is have the models pointers waiting before the call and passed in as variables. void MD3Character::LoadPlayer(char *path, char *skin, model* lower, model* upper, model* head )
this way when your done doing the new, its puts it in the ones that have a greater scope. If you then have your entire game ran from inside a single clss having the 3 model*'s as part of that class will keep them for the duration. ...

Wrong again. lower, upper and head are clearly member variables and therefore their lifetime is the same as that of the class instance.
Quote:
Sorry if my msg doesnt come accross well ... Im practically falling asleep ... TSCrusader has anyquestions he can se the messaging service to ask and will get a direct answer with in no longer then 2 days

I'm afraid I have to recommend that TSCrusader not contact you in private because I have no confidence that your answer would be correct. Better to keep it to a public board where inaccuracies can be corrected. Not that I don't appreciate your willingness to help.

Unfortunately there are too many possibilities for why this could crash. The most obvious ones appear to have been ruled out. Bounds checking and using the C++ standard library (i.e. std::string can help eliminate memory problems. I'd recommend you start there.

Σnigma
TSCrusader
TSCrusader
But it worked before i changed the md3models to md3model*, so the bounds should be correct, shouldnt they?
Also the First class, that really loaded these models, also works fine. Only the second class crashes when trying to use the first ones models...

another simple question:
how can i pass one element of an array of pointers so that the function can modify this?

MD3Model** models;

modelpool = new MD3Model*[10];

then pass models[0] ie to a function so that this function can fill this pointer.
rip-off
rip-off
Quote:

another simple question:
how can i pass one element of an array of pointers so that the function can modify this?

MD3Model** models;

modelpool = new MD3Model*[10];

then pass models[0] ie to a function so that this function can fill this pointer.


Like this:

void FillModel( MD3Model* ){   //stuff}void foo(){   MD3Model** modelpool ;   modelpool = new MD3Model*[10];   for( int i = 0 ; i < 10 ; ++i )   {       FillModel( modelpool );   }}



Consider using std::vector instead:

void FillModel( MD3Model* ){   //stuff}void foo(){   vector<MD3Model*> modelpool(10);   for( int i = 0 ; i < modelpool.size() ; ++i )   {       FillModel( modelpool );   }}
TSCrusader
TSCrusader
ahh k thx tested it now like this:

modelpool = new MD3Model*[10];

modelpool[1] = new MD3Model();
modelpool[2] = new MD3Model();
modelpool[3] = new MD3Model();
cha.LoadPlayer("klesk\\","red", modelpool[1],modelpool[2],modelpool[3]);

player->SetPlayer("klesk\\",modelpool[1],modelpool[2],modelpool[3]);



void MD3Character::LoadPlayer(char *path, char *skin, MD3Model* lower, MD3Model* upper, MD3Model* head)
void MD3Character::SetPlayer(char *path, MD3Model *lower, MD3Model *upper, MD3Model *head)


debug works. release crashes at the same line :(
so it really has nothing to do with the scope. hmmmmm

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.