14

这是我的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()功能中打印。

4

3 回答 3

19

您需要在 (*argv) 周围添加一对括号以更改评估顺序。你目前拥有它的方式,首先评估 [1],产生一个无效的指针,然后被取消引用,导致未定义的行为。

printf("%s\n", (*argv)[1]);
于 2012-04-29T01:13:50.233 回答
13

argv 已经是一个指针。像这样传递它:

init_arg(&argc, argv);

init_arg 应该是这样的:

void init_arg(int *argc, char **argv) {
    printf("%s\n", argv[1]);
}
于 2012-04-29T01:22:05.727 回答
2

我假设传递的原因&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;
}

当然这意味着你不能做 early returns inside init_arg,所以有一些权衡,但使用相同的常规 oldargcargvinside肯定要容易得多init_arg

于 2012-04-29T02:25:57.230 回答