Указатель файла не будет инициализирован в отдельной функции (ошибка seg на fclose) - PullRequest
1 голос
/ 01 декабря 2011

кк. Мне нужно понять жизнь. когда я передаю fp, указатель файла, в новую функцию и открываю ее там, fclose (fp) вызывает ошибку сегмента! и я обнаружил, что указатель файла, fp, никогда не был открыт.

main(int argc, char *argv[])
{
   File *fp;
   //*argv == filename
   functionToOpenFile(fp,*argv);
   //do stuff
   fclose(fp);
}

functionToOpenFile(File *fp, char *filename)
{
   fp = fopen(filename,"w");
   //error handling not shown
}

Мое решение, которое работает, состоит в том, чтобы передать адрес fp, который является указателем на указатель на файл. я не понимаю, почему это меняет вещи

main(int argc, char *argv[])
{
   File *fp;
   //*argv == filename
   functionToOpenFile(&fp,*argv);
   //do stuff
   fclose(fp);
}

functionToOpenFile(File **fp, char *filename)
{
   *fp = fopen(filename,"w");
   //error handling not shown
}

-AUstin

Ответы [ 3 ]

3 голосов
/ 01 декабря 2011

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

2 голосов
/ 01 декабря 2011

Вы не изменяете переданный указатель, вы только меняете его локальную копию. Поэтому, естественно, в конце функции для вызывающей стороны это выглядит так, как будто functionToOpenFile ничего не сделал . Попробуйте это:

functionToOpenFile(FILE **fp, char *filename)
{
   *fp = fopen(filename,"w");
}

/* ... */
functionToOpenFile(&fp,*argv);

Существует C FAQ , описывающий эту точную проблему.

0 голосов
/ 01 декабря 2011

А как же

int main(int argc, char *argv[])
{
   FILE *fp;
   //*argv == filename
   fp = functionToOpenFile(argv[1]); // better than argv[0] aka *argv.
   if (fp) {
        //do stuff
        fclose(fp);
   } else {
       // error occurred, but has already been dealt with.
   }
}

FILE * functionToOpenFile(char *filename)
{
   FILE * fp = fopen(filename,"w");
   //error handling not shown
   return fp;
}
...