int main(int argc, char* argv[])
{
int num = atoi(argv[1]);
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage:\tpartner1 (nameIndex)\n");
exit(EXIT_FAILURE);
}
if (num < 0 || num > 2) {
printf("nameIndex must be in[0, 1, 2]");
exit(EXIT_FAILURE);
}
вывод
./parent1
Segmentation fault
Я получаю ошибку сегментации, и я не уверен, почему это происходит. Я знаю, что второй оператор if работает нормально, потому что если я ввожу ./partner1 4 или ./partner1 -1, вывод будет
nameIndex must be in[0, 1, 2]
Почему это происходит?
Благодарность
2 ответа
Переместите int num = atoi(argv[1]);
ниже отметки argc
. Таким образом, вы будете проверять argv[1]
, только если знаете, что он существует.
int main(int argc, char* argv[])
{
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage:\tpartner1 (nameIndex)\n");
exit(EXIT_FAILURE);
}
int num = atoi(argv[1]);
if (num < 0 || num > 2) {
printf("nameIndex must be in[0, 1, 2]");
exit(EXIT_FAILURE);
}
Аргумент argv
функции main
является указателем на массив argc
указателей на строки, за которым следует указатель NULL
. argv[0]
указывает на C-строку имени программы, а argv[1]
на argv[argc - 1]
будет указывать на аргументы командной строки.
Например, если вы выполняете такую программу, как ./program hello world
, argc
будет 3
, а argv
будет указателем на массив, который выглядит так:
+------------------------+----------------------+----------------------+------+
| <pointer to "program"> | <pointer to "hello"> | <pointer to "world"> | NULL |
+------------------------+----------------------+----------------------+------+
Если вы подтвердили, что argc == 3
, то вы знаете, что можете получить доступ к строкам, на которые указывают argv[0]
, argv[1]
и argv[2]
.
Без аргументов, выполнив ./program
, вы получите что-то вроде:
+------------------------+------+
| <pointer to "program"> | NULL |
+------------------------+------+
Вы можете видеть, что argv[1]
— это указатель NULL
, который нельзя разыменовать (вы не можете получить доступ к данным, на которые он указывает).
Функция atoi
получит доступ к строке, на которую указывает аргумент, и это не может быть NULL
.
Вы всегда должны проверять значение argc
и/или последовательно проходить через массив argv
, проверяя NULL
. Ваш код получит доступ к argv[1]
до того, как проверит значение argc
, что вызовет разыменование указателя NULL
, что приведет к сбою.
Строка с atoi
должна быть перемещена после точки, где вы отметили argc
.
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.
argv[1]
будетNULL
. Эта строка должна появиться только после того, как вы проверили количество аргументов.argv
, чем указано в количествеargc
.#include <stdio.h>
и#include <stdlib.h>
, а также в вашей программе отсутствует}
в конце, поэтому она даже не должна компилироваться.