Sign in to follow this  
Kris2456

Dynamic memory problem (again)

Recommended Posts

As usual i am having problems with dynamic memory. I made my own loader for OBJ files. It compiles without errors, but i get the usual segmentation fault. I have debugged it. And it turns out that when the reader tries to read in a float to members of a dynamic CVector3 array, it crashes. I have posted some code below, and marked important points:
bool CIrisOBJmodel::LoadOBJ(LPSTR strName)
{
    if(!strName){
        return false;
        IrisLogger.Write("-1");}
    
//These are member pointers defined in the .h file
    Verticies = NULL;
    Normals   = NULL;
    UVcoords  = NULL;
    Faces     = NULL;
    
    VertArray = NULL;
    NormalArray   = NULL;
    UVcoordArray  = NULL;
    
    pFile = fopen(strName,"r");
    
    if(!pFile){
        return false;
        IrisLogger.Write("0");}

    
    //Count the amount of verts, normals, etc
//This counter works correctly, i have checked it
    CountLines();
    
    //Assign memory for stuff
//The numVert... etc are the correct value
    Verticies = new CVector3[numVerticies];
    Normals   = new CVector3[numNormals];
    UVcoords  = new CVector2[numUVcoords];
    Faces     = new CFace3[numFaces];
    
    VertArray = new CVector3[numVerticies];
    NormalArray   = new CVector3[numNormals];
    UVcoordArray  = new CVector2[numUVcoords];
    IrisLogger.Write("1");
        
    //Read it in
//Debugger crashes in this ReadFile() function
    ReadInFile();
    //Pack into vertex arrays
    PackIntoArray();
    
    //close file
    fclose(pFile);
    
    return true;
}


void CIrisOBJmodel::ReadInFile()
{
    char strline[255];
    char ch;
    char nch;
    int X, xv=1, xt=1, xn=1, xf=1;
    
    //while file not read through
//The whole while, switch loop works correctly
    for(X= 0;X<=numLines;X++)
    {
        ch = fgetc(pFile);
        switch(ch)
        {
            case 'v':
                //Read in some type of vertex
                //get another char
                nch = fgetc(pFile);
                
                if(nch==' ')
                {
                    //its a vert
//The debbugger crashes here, when floats are read into arrays
                    fscanf(pFile,"%f %f %f\n",Verticies[xv].x,Verticies[xv].y,Verticies[xv].z);
                    ++xv;
                }
                else if(nch=='t')
                {
                    //its a UVcoord
                    fscanf(pFile,"%f %f\n",UVcoords[xt].x,UVcoords[xt].y);
                    ++xt;
                }
                else
                {
                    //its a normal
                    fscanf(pFile,"%f %f %f\n",Normals[xn].x,Normals[xn].y,Normals[xn].z);
                    ++xn;
                }
                fscanf(pFile,"%s\n",strline);
                
            break;
            
            case 'f':
                //Its a face
                //for OBJ files, the CVector3's are used as an index
                //Order is vert/UVcoord/normal
                fscanf(pFile,"%f/%f/%f %f/%f/%f %f/%f/%f\n",Faces[X].vx,Faces[X].tx,Faces[X].nx,
                                                            Faces[X].vy,Faces[X].ty,Faces[X].ny,
                                                            Faces[X].vz,Faces[X].nz);
          
            break;
            
            default:
            //Probably a comment or something, next line
            fgets(strline, 100, pFile);
            break;
        }
    }
}

Share this post


Link to post
Share on other sites
Just glanced over your code real quick... but if i recall correctly, fscanf takes a reference to the variable to store the values into.

So, when you

fscanf(pFile,"%f %f",Faces[X].vx, Faces[X].tx);

what you really want to be doing is

fscanf(pFile,"%f %f",&(Faces[x].vx),&(Faces[X].tx));

Hope that helps.

Share this post


Link to post
Share on other sites
I never use C-style I/O so i might be wrong but your probably screwing up on this line:


fscanf(pFile,
"%f/%f/%f %f/%f/%f %f/%f/%f\n",
Faces[X].vx,Faces[X].tx,Faces[X].nx,
Faces[X].vy,Faces[X].ty,Faces[X].ny,
Faces[X].vz,Faces[X].nz);



your saying the format has 9 floats but your reading only 8, and on top that your not passing the address of the variables to fscanf.

Your using C++ already so why not just use C++ I/O facilities which are more safe if still wont to use format strings then you can use boost format lib, and instead of using raw C-style dynamic arrays use a vector e.g.


std::vector<CVector3> verticies;
verticies.reserve(numVerticies);


[Edited by - snk_kid on October 17, 2004 5:50:30 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid


std::vector<CVector3> verticies;
verticies.reserve(numVerticies);


thats how the tutorial did it. But i didnt want to use that beacuse i dont understand std::vector's or templates.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kris2456
Quote:
Original post by snk_kid


std::vector<CVector3> verticies;
verticies.reserve(numVerticies);


thats how the tutorial did it. But i didnt want to use that beacuse i dont understand std::vector's or templates.


Really you don't need to understand it you can just use it and reap the benefits, vector is a dynamic array that handles memory management, grows when needs to among other things all for you, if you wont to use vector with no change in your above code then simply:


std::vector<CVector3> verticies(numVerticies);


or:


std::vector<CVector3> verticies;// construct empty
/* ... */
verticies.resize(numVerticies);


will do the job, also vector has an overloaded subscript operator so you can just use it exactly like a C-style array.

you can get table of operations for vector here and STL in general here

Share this post


Link to post
Share on other sites
Your problem might be that you start indexing from 1.

On this line
int X, xv=1, xt=1, xn=1, xf=1;
You set xv to 1. But you only make the vertices array the size of numVertices. So the last vertex you read will overwrite the bounds. The same applies to xt, xn, and xf too.

Remember that array indexing is zero-based in c++.

Share this post


Link to post
Share on other sites
Quote:
Original post by fredizzimo
Your problem might be that you start indexing from 1.

On this line
int X, xv=1, xt=1, xn=1, xf=1;
You set xv to 1. But you only make the vertices array the size of numVertices. So the last vertex you read will overwrite the bounds. The same applies to xt, xn, and xf too.

Remember that array indexing is zero-based in c++.

I concur, doctor.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this