1

Cのポインタについて助けが必要です。構造体が次のように作成した2つの構造体があります。

    typedef struct s{
        s2** d;
        struct s* next;
    }s;


 typedef struct s2{
        c* fi;
        struct s2* next;
    }s2;

そして、私はこのような機能を持っています:

void modify(c* a, s2* b){   //c* is a pointer to a struct
    s* rd = malloc(sizeof(s);
    rd->next = NULL;
    //need also to initialize the field "d" of the "s" struct
}

これはエラーを生成しています。例のように、bを指す構造rdが必要です。s2はリストのようにリンクされているため、ダブルポインターを格納する必要があります。したがって、リストの最初の要素を削除できるようにするには、**ポインターが必要です。コメントでrd->d=&bのように割り当てを行っていましたが、関数のフィールド "d"を参照しようとすると、無効なメモリが読み取られ、その理由がわかりません。

4

1 に答える 1

1

問題はこれだと思います:

s2* bに引数として渡すためmodify、このポインタはスタック上にあります。これで、を割り当てるときrd->d = &bに、スタック上のその場所を取得します。これは、実行が。のスコープを離れるまでのみ有効ですmodify。したがって、後で逆参照するときrd->dに、スタック上のその(現在は無効な)場所にアクセスします。これにより、ガベージまたはクラッシュが発生します。rd->d(ただし、このシナリオでは、まだいる間に正しく逆参照できるはずですmodify。)

bおそらく、modifyに渡される方法を変更したいと思うでしょう。おそらく、のようなものに渡されます。そうすれば、のスタックに置かれることへのポインターではなく、別の構造体s2** bへのポインターへのポインターを正しく渡すことができます。s2s2modify

基本的にこのように:

void modify(c* a, s2** b) {
    s* rd = malloc(sizeof(s));
    rd->next = NULL;
    rd->d = b;
}

そしてそれを次のように呼びます

s2* myS2 = ...;
modify(<whatever>, &myS2->next);

s2これにより、ポインタの場所をインスタンスに渡して、modify終了後も保存して逆参照できるようになります(ただし、テストされていません)。

于 2011-03-19T14:29:32.753 に答える