2016-03-09 3 views
1

Я пишу код для хранения данных из текстового файла. Код компилируется, но, похоже, он перестает работать в цикле for в функции ReadPanelBlock. Он структурирован как: CHBStructure содержит CHBPanels который содержит CHBOpenings. Функции были созданы для чтения из входного текстового файла, который я организовал в блоки данных для удобства чтения.Управление конструкцией и массив структур

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: Я попытался трассировку, где ошибка возникает при печати текста в каждой строке и, кажется, врезаться в первой функции fscanf в функции ReadPanelBlock.

ответ

2

Доступ к S->panels[i]->openings[j]: UB, потому что вы не выделили место для этого массива.

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

     // inner for 
    } 

Предварительно выделенное пространство для openings указателя с:

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

вызовет утечку памяти, потому что код не освободит эту память из-за того, что адрес будет потерянной j внутренней for с код

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

Вы можете избежать иметь указатель и написать

 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); 
     } 

В вашей структуре CHBPanel *panels[]; и CHBOpening *openings[]; должны быть:

CHBPanel *panels; 
CHBOpening *openings; 

И последнее, но не менее важное, что вы должны изучить кое-что о указателей и -> и . использования.

Ваш код должен быть как:

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; 
} 
+0

Я попытался вставить таНос линию как раз перед внутренним для как Вы предложили, но теперь сообщается недопустимое использование гибкого элемента массива. –

+0

это очень помогает! в синтаксисе нет проблем, но программа по-прежнему падает. Я проверил некоторые проверки, и кажется, что указатель файла не читает значения из файла, поэтому члены структурных открытий имеют значения 0.0. Программа также не возвращается к внешнему циклу и останавливает процесс на последней итерации внутреннего цикла. Есть предположения? Спасибо еще раз за помощь! –

+0

@CarlChesterRagudo Первое предположение: 'S-> nPanels = 1', и вы должны проверить, как данные упорядочиваются в исходный файл. Отправьте новый вопрос с вашим кодом и образцом содержимого файла. – LPs

Смежные вопросы