Если вызывается fclose (0), закрывает ли это стандартный ввод? - PullRequest
12 голосов
/ 10 мая 2011

Если вызывается fclose (0), это закрывает стандартный ввод?

Причина, по которой я спрашиваю это, заключается в том, что по какой-то причине stdin закрывается в моем приложении, и я не могу понять, почему. Я проверил fclose (stdin), а его нет в приложении, поэтому мне было интересно, может ли fclose (0) вызвать неопределенное поведение, например закрытие stdin?

Если нет, то как еще можно ошибочно закрыть стандартный ввод?

Ответы [ 4 ]

18 голосов
/ 10 мая 2011

Подпись fclose такова:

int fclose ( FILE * stream );

Это означает, что fclose ожидает указатель на FILE объект. Таким образом, если вы передадите 0 вместо указателя, 0 будет восприниматься как NULL указатель 1 . Если указатель NULL, как вы ожидаете, что он закроет stdin? Это не закроется. Используйте fclose(stdin), так как stdin сам по себе является указателем на FILE объект.

Я думаю, вы путаете stdin с файловым дескриптором, который имеет целочисленный тип и обычно обозначается как fd. Это правда, что fd входного потока равен 0. Так что если вы хотите использовать fd (вместо FILE*), то вам нужно использовать close из <unistd.h>.

#include <unistd.h>
int close(int fildes);

То есть close(0) закроет стандартный ввод.

1: Интересно, что если вы передали 1 в fclose с намерением закрыть stdout, ваш код даже не скомпилировался бы, и вы сразу увидели бы проблему с вашим кодом во время самой компиляции. Теперь вопрос в том, почему он не скомпилируется? Потому что в отличие от 0, 1 неявно не преобразуется в тип указателя. Компилятор сгенерирует сообщение типа "error: invalid conversion from ‘int’ to ‘FILE*’. Смотрите ошибку и номер строки здесь на ideone .

6 голосов
/ 10 мая 2011

Следующее закрывает стандарт: close(0); fclose(stdin); close(STDIN_FILENO); daemon(0, 0);

6 голосов
/ 10 мая 2011

Я думаю, это будет восприниматься как fclose(NULL);Который должен быть неопределен и может привести к сбою.

5 голосов
/ 10 мая 2011

fclose(0) вызывает неопределенное поведение , так что да, он может делать что угодно, включая закрытие stdin.Но у вас гораздо большие проблемы, если в вашем коде появляется fclose(0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...