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;
}

もちろん、これは、return内部init_argで初期のsを実行してはならないことを意味するため、いくつかのトレードオフがありますが、同じ通常の古い内部argcで作業する方がはるかに簡単です。argvinit_arg

于 2012-04-29T02:25:57.230 に答える