简体   繁体   中英

Struct handling and array of structs

I am writing a code to store data from a text file. The code compiles but it seems to stop running in the for-loop in the ReadPanelBlock function. It is structured as: CHBStructure contains CHBPanels which contains CHBOpenings . The functions were created to read from an input text file which I organized into data blocks for easy reading.

typedef struct _open
{
    int id;
    double length;
    double height;
    double origX;
    double origY;
    int frames;

    double thickness;
    double E;
    double v;
}CHBOpening;

typedef struct _panels
{
    int id;
    double length;
    double height;
    double origX;
    double origY;
    double origZ;
    double angle;
    int nOpenings;
    int nReinforcement;
    double *xReinf;
    double sx;
    double xReinf0;

    CHBUnit *chb;
    CHBOpening *openings[];
}CHBPanel;

typedef struct _chb
{
    int nStories;
    int nModes;
    int nIter;
    int nPanels;
    CHBPanel *panels[];
}CHBStructure;

int ReadPanelBlock (FILE *fp, CHBStructure *S)
{
    CHBOpening *openings = malloc(sizeof(CHBOpening));
    *S->panels = malloc(S->nPanels*sizeof(CHBPanel));
    for (i=0; i<S->nPanels; i++)
    {
        fscanf(fp,"%d",&S->panels[i]->id);
        fscanf(fp,"%lf",&S->panels[i]->length);
        fscanf(fp,"%lf",&S->panels[i]->height);
        fscanf(fp,"%lf",&S->panels[i]->angle);
        fscanf(fp,"%lf",&S->panels[i]->origX);
        fscanf(fp,"%lf",&S->panels[i]->origY);
        fscanf(fp,"%lf",&S->panels[i]->origZ);
        fscanf(fp,"%d",&S->panels[i]->nOpenings);
        if (S->panels[i]->nOpenings > 0)
        {
            for (j=0; j<S->panels[i]->nOpenings;j++)
            {
                openings = S->panels[i]->openings[j];
                fscanf(fp,"%d",&openings->id);
                fscanf(fp,"%lf",&openings->length);
                fscanf(fp,"%lf",&openings->height);
                fscanf(fp,"%lf",&openings->origX);
                fscanf(fp,"%lf",&openings->origY);
            }
        }
    }
    return 1;
}

EDIT 1: I tried tracing where the error occurs by printing text in each line and it seems to crash in the first fscanf function in the ReadPanelBlock function.

Accessing S->panels[i]->openings[j] is UB , because you did not allocate space for that array.

    if (S->panels[i].nOpenings > 0)
    {
         S->panels[i].openings = malloc(sizeof(CHBPanel)*S->panels[i].nOpenings);

         // inner for
    }

Pre allocated space for openings pointer with:

CHBOpening *openings = malloc(sizeof(CHBOpening));

will cause memory leak, because no code will free that memory due to the fact that the address will be lost by the j inner for with code

openings = S->panels[i]->openings[j];

You can avoid to have a pointer and write

        for (j=0; j<S->panels[i].nOpenings;j++)
        {
            fscanf(fp,"%d",&S->panels[i].openings[j].id);
            fscanf(fp,"%lf",&S->panels[i].openings[j].length);
            fscanf(fp,"%lf",&S->panels[i].openings[j].height);
            fscanf(fp,"%lf",&S->panels[i].openings[j].origX);
            fscanf(fp,"%lf",&S->panels[i].openings[j].origY);
        }

In your structure CHBPanel *panels[]; and CHBOpening *openings[]; have to be:

CHBPanel *panels; 
CHBOpening *openings;

Last but not least thing: you must study something about pointers and -> and . usage.

Your code should be like:

int ReadPanelBlock (FILE *fp, CHBStructure *S)
{
    int i,j;
    S->panels = malloc(S->nPanels*sizeof(CHBPanel));
    for (i=0; i< S->nPanels; i++)
    {
        fscanf(fp,"%d",&S->panels[i].id);
        fscanf(fp,"%lf",&S->panels[i].length);
        fscanf(fp,"%lf",&S->panels[i].height);
        fscanf(fp,"%lf",&S->panels[i].angle);
        fscanf(fp,"%lf",&S->panels[i].origX);
        fscanf(fp,"%lf",&S->panels[i].origY);
        fscanf(fp,"%lf",&S->panels[i].origZ);
        fscanf(fp,"%d",&S->panels[i].nOpenings);
        if (S->panels[i].nOpenings > 0)
        {
            S->panels[i].openings = malloc(sizeof(CHBOpening)*S->panels[i].nOpenings);

            for (j=0; j<S->panels[i].nOpenings;j++)
            {
                fscanf(fp,"%d",&S->panels[i].openings[j].id);
                fscanf(fp,"%lf",&S->panels[i].openings[j].length);
                fscanf(fp,"%lf",&S->panels[i].openings[j].height);
                fscanf(fp,"%lf",&S->panels[i].openings[j].origX);
                fscanf(fp,"%lf",&S->panels[i].openings[j].origY);
            }
        }
    }
    return 1;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM