web-dev-qa-db-ja.com

C構造体へのダブルポインター

私はCの構造体への二重ポインターを解決しようとしていますが、何がうまくいかないのか理解できません...単純なソースは以下のとおりです。

typedef struct
{
    int member;
} mystruct;

void myfunc(mystruct **data)
{
    (*data)->member = 1;
}

void main(int argc, char *argv[])
{
    mystruct **data;

    myfunc(data);

    printf("member = %d\n", (*data)->member);
}

同様の質問がここで尋ねられました: Cでの構造体へのポインターへのポインターを使用する方法? 二重ポインターを介して構造体のメンバーを変更する方法について。解決策は構文(*data)->member = 1;理にかなっています。しかし、ここの小さなアプリケーションでは、その行を実行すると、seg faultが発生します。何が悪いのですか?

ありがとう

23
linsek

ポインターを逆参照する場合は、何かを指す必要があります。これを試して:

void main(int argc, char *argv)
{
    mystruct actualThing;
    mystruct *pointer = &actualThing;
    mystruct **data = &pointer;
    myfunc(data);

    printf("Member: %d", (*data)->member);
}
20
DwB

構造体を割り当てなかったため、segfaultを受け取りました。

dataの値はガベージであるため、プロセスが所有していないか、アクセスできないメモリ内の場所をポイントしています。

最初に、タイプmystructのオブジェクトを割り当てる必要があります。これはあなたのための実用的な例です: http://ideone.com/XIdJ8

7
Ray Toal

dataは初期化されていないため、適切なメモリアドレスを指していません。さらに、_mystruct構造が浮いているわけではないので、実際に指し示す必要のあるデータさえありません。あなたの例では、次のことを行います:

  1. mystructを作成します。
  2. それへのポインタを作成します。
  3. そのポインタへのポインタを作成します。
5
gspr

ライブラリ関数にダブルポインターを渡すだけでよい場合は、そのための変数を作成する必要はありません。通常のポインター変数を作成し、適切なストレージを指すように初期化し(関数で必要な場合)、ポインターのアドレスを渡します(したがって、「オンザフライ」でダブルポインターを作成します)。

私はlibusbを使用したことがないので、標準のライブラリー関数を使用した例を示します。マンページから:

   #include <stdlib.h>

   long int strtol(const char *nptr, char **endptr, int base);

ダブルポインタのようにlooksのみです。これは、実際には参照渡しのシミュレートされた単一のポインターです。関数が通常の戻り値以外の追加情報を返すことができるようにします。 strtolは長整数を返しますが、文字列の内容が数値のように見えなくなった時点もわかります。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *str = "99RED BALLOONS";
    char *what;
    long num;

    num = strtol(str, &what, 10);
    printf("Quantity: %ld;    Description: %s;\n", num, what);

    return 0;
}

出力:

Quantity: 99;    Description: RED BALLOONS;
1
luser droog

あなたはそれにポインターを渡していますが、ポインターは何も指していません。

これはもっと便利かもしれません:

void main(int argc, char *argv[])
{
    mystruct data;
    mystruct *ptr = &data;
    myfunc(&ptr);
    printf("member = %d\n", (*ptr)->member);
}
0
Chris Eberle