Указатель файла не будет инициализирован в отдельной функции (ошибка seg при fclose)

кк. мне нужно понять жизнь. когда я передаю fp, указатель файла, в новую функцию и открываю ее там, fclose(fp) вызывает ошибку seg! и я обнаружил, что указатель файла 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
}

-Остин


person austin    schedule 01.12.2011    source источник


Ответы (3)


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

person LostMohican    schedule 01.12.2011

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

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

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

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

person cnicutar    schedule 01.12.2011
comment
конечно! я должен разыменовать любой указатель, если я хочу изменить данные в моей вызывающей функции - person austin; 02.12.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;
}
person glglgl    schedule 01.12.2011
comment
Код ошибки немного перепутался... Разве FILE * functionToOpenFile(char *filename) не должно быть FILE * functionToOpenFile(FILE **fp, char *filename) и *fp = fopen(..) ? Может быть, тип возврата также можно изменить? - person another.anon.coward; 01.12.2011