Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
__progname
не является стандартным и поэтому не портативным, предпочтите argv[0]
. Я предполагаю __progname
, мог поиск строковый ресурс для завоевывания репутацию, который не зависит от имени файла, Вы выполнили его как. Но argv[0]
даст Вам имя, они на самом деле выполнили его как, который я найду более полезным.
Используя __progname
позволяет Вам изменять содержание эти argv[]
массив, все еще поддерживая название программы. Некоторые общие инструменты такой как getopt()
изменяют argv[]
, поскольку они обрабатывают аргументы.
Для мобильности, Вы можете strcopy argv[0]
в Ваше собственное progname
буфер, когда Ваша программа запускается.
Я вижу по крайней мере две потенциальных проблемы с argv [0].
Первый, argv [0] или сам argv может быть ПУСТЫМ, если execve () вызывающая сторона был злым или достаточно небрежным. Вызов execve ("foobar", ПУСТОЙ УКАЗАТЕЛЬ, ПУСТОЙ УКАЗАТЕЛЬ) обычно является простым и интересным способом доказать по уверенному программисту, его код не sig11-защищен.
нужно также отметить, что argv не будет определен за пределами основного (), в то время как __ progname обычно определяется как глобальная переменная, можно использовать из использования (), функция или даже прежде основной () вызвана (как нестандартные конструкторы GCC).
Если Ваша программа была запущена с помощью, например, символьная ссылка, argv [0] будет содержать название той ссылки.
я предполагаю, что __ progname будет содержать название фактического программного файла.
В любом случае, argv [0] определяется стандартом C. __ progname не.
Для этого также существует расширение GNU, так что можно получить доступ к имени вызова программы извне main (), не сохраняя его вручную. Однако, возможно, лучше сделать это вручную; что делает его переносимым, а не полагаться на расширение GNU. Тем не менее, я привожу отрывок из доступной документации.
Из интерактивного руководства по библиотеке GNU C (доступ сегодня):
«Многие программы, которые не считывают ввод с терминала, предназначены для выхода, если какой-либо системный вызов терпит неудачу. По соглашению , сообщение об ошибке такой программы должно начинаться с имени программы без каталогов. Вы можете найти это имя в переменной program_invocation_short_name
; полное имя файла хранится в переменной program_invocation_name
.
Переменная: char * имя_вывода_программы
Значение этой переменной - это имя, которое использовалось для вызова программы, запущенной в текущем процессе. Это то же самое, что argv [0]
. Обратите внимание, что это не обязательно полезное имя файла; часто он не содержит имен каталогов.
Переменная: char * краткое_имя_программы
Значение этой переменной - это имя, которое использовалось для вызова программы, запущенной в текущем процессе, с удаленными именами каталогов. (То есть это то же самое, что и имя_программы
за вычетом всего до последней косой черты, если есть.)
Код инициализации библиотеки устанавливает обе эти переменные перед вызовом main.
Примечание о переносимости: Эти две переменные являются расширениями GNU.Если вы хотите, чтобы ваша программа работала с библиотеками, отличными от GNU, вы должны сохранить значение argv [0]
в main, а затем самостоятельно удалить имена каталогов. Мы добавили эти расширения, чтобы сделать возможным писать автономные подпрограммы сообщения об ошибках, которые не требуют явного взаимодействия с main. "