проблема с fprintf - PullRequest
       27

проблема с fprintf

1 голос
/ 11 марта 2011

Я запускаю симуляцию в C, и мне нужно хранить 3 матрицы 100x100 ~ 1000 раз.Моя программа работает нормально, когда я не записываю данные в файл.Но когда я запускаю свою программу и записываю данные, я получаю ошибку сегментации после 250 временных шагов или около того.И я не понимаю, почему.

Моя функция сохранения выглядит следующим образом

void saveData(Simulation* sim, int number) {
   sprintf(pathname_vx, "data/xvel%d.dat", number);
   sprintf(pathname_vy, "data/yvel%d.dat", number);
   sprintf(pathname_rho, "data/rho%d.dat", number);
   FILE* vx_File = fopen(pathname_vx, "w");
   FILE* vy_File = fopen(pathname_vy, "w");
   FILE* rho_File = fopen(pathname_rho, "w");
   int iX, iY;
   double ux, uy, rho;
   for (iY=0; iY<sim->ly; ++iY) {
       for (iX=0; iX<sim->lx; ++iX) {
           computeMacros(sim->lattice[iX][iY].fPop, &rho, &ux, &uy);
           fprintf(vx_File, "%f ", ux);
           fprintf(vy_File, "%f ", uy);
           fprintf(rho_File, "%f ", rho);
       }
       fprintf(vx_File, "\n");
       fprintf(vy_File, "\n");
       fprintf(rho_File, "\n");
   }
   fclose(vx_File);
   fclose(vx_File);
   fclose(vy_File);
}

, где 'Simulation' - это структура, содержащая решетку (матрица 100x100) с 3 различными переменными 'rho''UX', 'UY'.Аргумент 'number' - это просто переменная подсчета для правильного именования файлов.

GDB говорит следующее, но мне это мало помогает.

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000010
0x00007fff87c6ebec in __vfprintf ()

Я не такойопыт в программировании, поэтому я думаю, что есть лучшие способы записать данные в файл.Любая попытка объяснить, почему мой подход не работает, высоко ценится.

Спасибо

Джон

Ответы [ 4 ]

6 голосов
/ 11 марта 2011

Похоже, вы закрываете vx_File дважды, а вовсе не закрываете rho_File.Это означает, что вы оставляете rho_File открытым каждую итерацию и, таким образом, каждый раз используете файловый дескриптор.

Я полагаю, что в программе происходит сбой, у вас заканчиваются файловые дескрипторы.(Поскольку это происходит на 250-й итерации, я предполагаю, что ваш лимит равен 256).Как только вы выйдете из файловых дескрипторов, один из вызовов fopen () вернет NULL.Поскольку вы не проверяете возвращаемое значение fopen (), сбой произойдет, когда вы попытаетесь переписать в дескриптор NULL.

4 голосов
/ 11 марта 2011

Похоже на разыменование нулевого указателя.Вам нужно проверить результат fopen (), чтобы убедиться, что он успешен (результат не NULL).

0 голосов
/ 11 марта 2011

Возможно, вам не хватает памяти, когда вы создаете эти тысячи матриц размером 100x100 (или что бы то ни было, что именно происходит).После этого вы можете получить неполный sim->lattice, который может содержать NULL указатели.

Проверяете ли вы, malloc() вызовы успешны?Если они не могут выделить память, они возвращают NULL.

0 голосов
/ 11 марта 2011

В gdb вы могли бы попробовать команду `bt '?Это покажет трассировку стека для сбойной функции.Что это говорит тебе?

...