Archived

This topic is now archived and is closed to further replies.

Program crashing

This topic is 5109 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

Hey all. Im (still) working on a big 3d online project, but Ive run into some trouble. Each time I want to load a new world, I call a function to do so. This function reads in scripts from ini-files, and loads 3ds models. It then generates displaylists of those models. The problem is, the function only works once. during startup, I call the function, and the initial world is loaded just fine. If I call it again later to laod a new one however, the entire program freezes. Can anyone tell me why?
void TMainform::LoadWorldFromIni(AnsiString FileName)
{
        /*

                Load in the main world/map/scene or whatever

        */
        AnsiString CorrectedFileName = ".\\data\\" + FileName;

        TIniFile *ini;

        if(FileExists(FileName))
                ini = new TIniFile( FileName );
        else
                ini = new TIniFile( CorrectedFileName );

        // We need the following
        // - world id
        // - number of objects in it
        // - world mesh
        // - the id''s of the objects in the world

        // Read the ID
        world_id = ini->ReadInteger( "Wereld", "ID", 1 );

        // Number of objects
        num_objects = ini->ReadInteger( "Wereld", "Aantal", 0 );
        
        // World mesh
        AnsiString world_mesh = ini->ReadString( "Wereld", "Wereld", "");

        // Player startposition
        AnsiString player_start = ini->ReadString("Wereld", "Start", "0,0,0");

        char *x, *y, *z;

        x = strtok(player_start.c_str(), ",");
        y = strtok(NULL, ",");
        z = strtok(NULL, ",");

        Player[PlayerID].Position.x = StrToFloat(x);
        Player[PlayerID].Position.y = StrToFloat(y);
        Player[PlayerID].Position.z = StrToFloat(z);

        // If there is an old mesh present, delete it first
        if(World_model)
        {
                delete World_model;
                World_model = 0;
        }

        // Load the model
        if(FileExists(world_mesh))
        {
                World_model = new CModel;
                World_model->Load(world_mesh.c_str() );

                WorldDisplaylist = glGenLists(1);
                
                glNewList(WorldDisplaylist, GL_COMPILE);
                World_model->Render();
                glEndList();
        }

        // Load all objectscripts
        for(int i = 1; i <= num_objects; i++)
        {
                AnsiString scriptline = ini->ReadString( "Wereld", "Object"+IntToStr(i), 0 );

                // Pointers to substrings. The id is at 0
                char *x, *y, *z, *xrot, *yrot, *zrot, *targetworld, *url;

                // Decipher the scriptline
                strtok(scriptline.c_str(), ",");
                x = strtok(NULL, ",");
                y = strtok(NULL, ",");
                z = strtok(NULL, ",");
                xrot = strtok(NULL, ",");
                yrot = strtok(NULL, ",");
                zrot = strtok(NULL, ",");
                targetworld = strtok(NULL, ",");
                url = strtok(NULL, ",");

                // Now convert these substrings into useable values
                worldobject[i-1].id = StrToInt(scriptline) - 1;
                worldobject[i-1].Position.x = StrToInt(x);
                worldobject[i-1].Position.y = StrToInt(y);
                worldobject[i-1].Position.z = StrToInt(z);
                worldobject[i-1].Rotation.x = StrToInt(xrot);
                worldobject[i-1].Rotation.y = StrToInt(yrot);
                worldobject[i-1].Rotation.z = StrToInt(zrot);

                worldobject[i-1].Targetworld = String(targetworld);

                if(worldobject[i-1].Targetworld == "0")
                        worldobject[i-1].Targetworld = "";

                worldobject[i-1].Url = String(url);

                if(worldobject[i-1].Url == "0")
                        worldobject[i-1].Url = "";
        }

        delete ini;	
}
 
Is it possible that it is caused by me trying to create new a displaylist of the world, even though the old one still exists? any help would be greatly appreciated

Share this post


Link to post
Share on other sites
Where does your program crash?

--------------------------------------------------------

"If it looks good, it is good computer graphics"
"If it looks like computer graphics, it is bad computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

Share this post


Link to post
Share on other sites
Are you sure the ini file is complete? The rest seems ok to me.
Try loading the same world twice, look if it crashes then, if not, the 2nd ini file you tried to load isn't complete.

Or:

Try to set breakpoints.

[edited by - Living Monstrosity on December 16, 2003 6:37:47 AM]

Share this post


Link to post
Share on other sites
Is AnsiString a self-written class? Maybe there are some memory problems?

--------------------------------------------------------

"If it looks good, it is good computer graphics"
"If it looks like computer graphics, it is bad computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

Share this post


Link to post
Share on other sites
OR you can try not deleting everything you new.
I got access violation when deleting (or freeing when using malloc) is some of my functions for no clear reason at all, so i simply commented all delete blabla lines and now it workt fine, the memory is even deleted automatically when the pointer''s scope expires.

Share this post


Link to post
Share on other sites
quote:
Original post by Living Monstrosity
OR you can try not deleting everything you new.
I got access violation when deleting (or freeing when using malloc) is some of my functions for no clear reason at all, so i simply commented all delete blabla lines and now it workt fine, the memory is even deleted automatically when the pointer''s scope expires.


This is extremely bad! The memory is not deleted automatically in C or C++. There is an error in your code if the deletes give you access violations(i.e. your deleting memory that wasn''t allocated or double deleting it). The only time the memory MAY be freed is when the program closes completely. In newer systems this happens i.e. XP/2000 but older OS''s 9x don''t do this so you will be losing some memory until you reboot. You should try to find out why it is crashing instead - you ARE doing something wrong!

James

Share this post


Link to post
Share on other sites
Try checking memory allocation and deallocation:

if you alloc with malloc() use free()

if you alloc with new use delete

if you alloc with new[] use delete[] <- (VERY important because if you alloc with new[] and want to use delete the state is UNDEFINED, you have to use delete[] to make everything work fine)

--------------------------------------------------------

"If it looks good, it is good computer graphics"
"If it looks like computer graphics, it is bad computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

Share this post


Link to post
Share on other sites
You should deallocate with

delete[] a;

delete[] is a seperate function just as delete but for arrays.


delete a[]; won't work at all. I don't think that this is valid.
delete a; Isn't valid too because the state is undefined.

--------------------------------------------------------

"If it looks good, it is good computer graphics"
"If it looks like computer graphics, it is bad computer graphics"

Corrail
corrail@gmx.at
ICQ#59184081

[edited by - Corrail on December 16, 2003 9:12:14 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Living Monstrosity
well, with this code:

if(p){
free(p);
};

// OR when using new


if(p){
delete p;
};

i get access violation, so does that mean that the array is allocated, but not really there?


pointer * p = new pointer;
delete p;

after that, the statement if(p) will still execute! Make sure you add p = NULL; after the delete.

Share this post


Link to post
Share on other sites
quote:
Original post by Corrail
You should deallocate with

delete[] a;

delete[] is a seperate function just as delete but for arrays.


delete a[]; won''t work at all. I don''t think that this is valid.
delete a; Isn''t valid too because the state is undefined.


While we''re on the subject, could someone give me an example where deleting an array MUST be done with delete[]?
I have the bad habbit of never, ever using delete[], and off the top of my head I can''t think of a time when it''s caused problems for me.
In my current project I''m allocating and dealocating lots of large arrays on the fly and I''m confident that my memory is being correctly freed. (It would run out of memory in seconds if the memory weren''t being freed properly.)

Does delete[] as opposed to delete only become important if the constructors or destructors of the array elements do something unusual?

I feel stupid asking such a basic question, but every time I read about this I never quite understand why it works this way. Thanks.

-Andy

Share this post


Link to post
Share on other sites
quote:
Original post by Ruudje
when using an array you always have to use []

Hmmmm... My compiler must realise how cool I am and fix it for me, then.

quote:
but could we plz go back to my problem now?

Is it possible that some other part of your program holds a pointer to the data structure that''s being deleted and then reallocated?
For instance if you had a "renderer" object with a pointer to some vertexes, it would crash during the next frame.

(About your object parser, you''re intentionaly throwing away the first token, right? And the LAST token on each line is .ID?)

Two other ideas occured to me that are probably not important at all unless you''re multi-threading, but I thought they were worth mentioning.
1) How would your program react if your renderer were called in the middle of this load operation?
2) strtok(...) isn''t thread-safe.

(P.S. Don''t forget to glDeleteLists.)

-Andy

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Hmmmm... My compiler must realise how cool I am and fix it for me, then.



Your compiler may be fixing it, but you can not rely on the compiler to do these things. You are probably just getting lucky with you compiler/machine set up. If you ran your code on enough computers, it most likely will cause problems on one of them. Calling delete on an item that was created with new[] is an UNDEFINED operation. That does not mean you can''t go right ahead and do it, it just means that you are can''t be sure what will happen. If you just use delete[] like you should, then you won''t have to worry.

Share this post


Link to post
Share on other sites
quote:
Original post by AndyL
quote:
Original post by Ruudje
when using an array you always have to use []

Hmmmm... My compiler must realise how cool I am and fix it for me, then.

quote:
but could we plz go back to my problem now?

Is it possible that some other part of your program holds a pointer to the data structure that''s being deleted and then reallocated?
For instance if you had a "renderer" object with a pointer to some vertexes, it would crash during the next frame.

(About your object parser, you''re intentionaly throwing away the first token, right? And the LAST token on each line is .ID?)

Two other ideas occured to me that are probably not important at all unless you''re multi-threading, but I thought they were worth mentioning.
1) How would your program react if your renderer were called in the middle of this load operation?
2) strtok(...) isn''t thread-safe.

(P.S. Don''t forget to glDeleteLists.)

-Andy



Well, it does, but any object deleted is re-allocated a few lines later...

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
quote:
Hmmmm... My compiler must realise how cool I am and fix it for me, then.



Your compiler may be fixing it, but you can not rely on the compiler to do these things. You are probably just getting lucky with you compiler/machine set up. If you ran your code on enough computers, it most likely will cause problems on one of them. Calling delete on an item that was created with new[] is an UNDEFINED operation. That does not mean you can''t go right ahead and do it, it just means that you are can''t be sure what will happen. If you just use delete[] like you should, then you won''t have to worry.


MSVC 6.0 at least, calls the same allocatin/deallocation routine no matter which version of new/delete you use.

You can do:
char *tmp = new char;
delete[] tmp;

char *tmp = new char[10];
delete tmp;

Both compile identically and work without issue, no matter how many machines you run it on, since it''s a compile time thing.

That said, I am not sure which compilers do this, and it''s a good habbit to do it correctly. Whenever you allocate an array, you should delete an array.

char *tmp = new char[10];
delete[] tmp;

And whenever you allocate a variable, you should delete a variable:
char *tmp = new char;
delete tmp;

Share this post


Link to post
Share on other sites
quote:
Well, it does, but any object deleted is re-allocated a few lines later...

Does what? If you have pointers into the area you''re deallocating and reallocating and you''re not updating the pointers this could be your problem. When you allocate the memory again it''s not guarantied to go to the same place...



Ready4Dis : Thanks. That explains it.

Share this post


Link to post
Share on other sites
well there is 1 pointer, and it points to a 3ds model loaded in. In addition there is 1 gluint pointing to a displaylist of that same model.

The model gets deleted through the global pointer.
The model then gets reloaded and the global pointer now points to the new model.
A new displaylist is formed using the new model.

Then again, I have no idea whats causing it, so it may not even be in the world-model stuff.

Share this post


Link to post
Share on other sites