-3

これは以前に尋ねられたことがあると思いますが、大雑把なグーグルとスタックオーバーフロー検索は答えを見つけませんでした。

#include <stdio.h>

int main() {
    char a[128][1024];
    strcpy(a[0], "hello");
    strcpy(a[1], "foo");
    strcpy(a[2], "bar");
    char **b = a;
    printf("%s\n", a[0]); //same as printf("%s\n", a)
    printf("%s\n", a[2]+1); //print from 2nd char of 3rd string
    printf("%s\n", b); //same as printf("%s\n", a), makes sense
    printf("%s\n", b[0]); //segfault???
}

まず、最後のセグメンテーション違反はなぜですか?配列と同じ動作を期待しaます。一般化された方法でbからn番目の文字列にアクセスするにはどうすればよいですか?aとbの治療の違いは何ですか?

同様に、私が理解しているのは、のa[n]構文糖衣です*(a+n)。これは、ポインターと配列の両方で正しいですか?それでも、との動作が異なるようaですb

ありがとう!

4

2 に答える 2

3

char **bb「ポイントがある場所b[0]に、文字へのポインタがあります。そして、私が、、…を使用する場合b[1]b[2]それらはcharへのポインタでもあります。」</ p>

対照的char a[128][1024]に、「<code>aは1024文字の128配列です。」と言います。これを行うと、ある場所にaはポインタがありません。ただのcharがあります。メモリでは、131,072文字が連続しているように見えます(128•1024 = 131,072)。

を割り当てるときはchar **b = a、コンパイラで許可されていると仮定して、bのアドレスに設定しますa。を使用する場合b[0]、そこにポインタがあるはずです。しかし、ありません。そこにはただのイワナがいます。printfに渡すb[0]と、コンパイラはbポイントに移動し、ポインタであるかのように数バイトをロードして、結果の値をprintfに渡します。次に、バイトが不適切な場所を指しているため、printfがクラッシュします。

の適切な定義はbですchar (*b)[1024] = a;

于 2012-11-02T16:36:08.277 に答える
0

これ

char **b = a;

インデックスなしで使用されるタイプの不一致aはです。char[][]char *

すべてのコンパイラの警告を切り替えることをお勧めします(gccこれは経由で行われ-Wallます)。

この行

printf("%s\n", b[0]); 

文字へのポインタ、つまりアドレス値へのポインタを間接参照します。次に、アドレス値の値を(0で終了する)文字列として出力しようとします。これは、ランダムメモリにアクセスする可能性が最も高い文字列です。

于 2012-11-02T16:27:24.480 に答える