Указатель на * argv []
Это мой main.c
......
int main(int argc, char **argv)
{
init_arg(&argc, &argv);
......
}
Это мой init_arg.c
......
void init_arg(int *argc, char ***argv)
{
printf("%s\n", *argv[1]);
......
}
Я компиляю его без ошибок и предупреждений.
Я запускаю его:
./a.out include
Он получает Ошибка сегментации
Когда я его отлаживаю, я нашел шаг printf("%s\n", *argv[1]);
Неправильно, он показывает:
print *argv[1]
Cannot access memory at address 0x300402bfd
Я хочу знать, как печатать argv[1]
в init_arg()
.
Ответы
Ответ 1
Вам нужно добавить пару круглых скобок (* argv), чтобы изменить порядок оценки. То, как вы в настоящее время его используете, сначала оценивается [1], что дает недопустимый указатель, который затем разыменовывается, вызывая поведение undefined.
printf("%s\n", (*argv)[1]);
Ответ 2
Аргв уже является указателем. Просто передайте его вот так:
init_arg(&argc, argv);
И init_arg должен выглядеть так:
void init_arg(int *argc, char **argv) {
printf("%s\n", argv[1]);
}
Ответ 3
Я предполагаю, что причина прохождения &argc
и &argv
в первую очередь заключается в том, что вы можете обновлять их внутри init_arg
. Вот как я предпочитаю писать такие функции, в общем случае:
/*
* init_arg: do something useful with argc and argv, and update argc and argv
* before returning so that the caller can do something else useful that's
* not shared with all the other callers of init_arg().
* (this comment of course needs updating to describe the useful things)
*/
void init_arg(int *argc0, char ***argv0) {
int argc = *argc0;
char **argv = *argv0;
... all the operative code goes here, and then ...
*argc0 = argc;
*argv0 = argv;
}
Конечно, это означает, что вы не должны делать ранние return
внутри init_arg
, поэтому есть некоторые компромиссы, но гораздо легче работать с теми же обычными старыми argc
и argv
внутри init_arg
.