1

わかりました、これはおそらく非常に単純ですが、ポインター、配列、およびメモリ割り当てについてサイト全体を調べましたが、いくつかの説明は私には少し複雑すぎます. それで... d[i] が以下のコードで異なるものを指している理由を誰かが私に説明できますか?

typedef struct data_t {
    int ival;
    char *sval;
} data_t;

void f1(data_t **d);
int main()
{
data_t *d; 
    d = new data_t[500];
    for (int i=0; i<500; i++)
    {
        d[i].ival= i+1;
        d[i].sval="$";
    }

    f1(&d); 
}

void f1(data_t **d)
{
    for (int i=0; i<500; i++)
    {
        d[i]->ival=i+1;
        d[i]->sval="$";
    }
}

私がする必要があるのは、整数フィールド「ival」が配列インデックス0〜499の値1〜500を持ち、文字列フィールド「sval」に文字列「$ 1」が含まれるように、配列の500要素のそれぞれを埋めることです」 – 配列インデックス 0 ~ 499 の場合は「$500」。関数呼び出しで。

も、また

d = new data_t[500]

構造体の 500 要素配列にメモリを割り当てる必要があるのは?

メインの for ループでは機能するが、関数呼び出しでは機能しない理由を理解しようとしているだけです...デバッガーを見ると、ポインターは何か間違ったことを指しています...

4

2 に答える 2

4

は と同じなmainので「効く」。あなたの関数では、 はポインターへのポインターであるため、etc と言う必要があります(あなたが書いた は、ポインターへのポインターを段階的に進めてから、それを逆参照しようとします、これは間違った方法です)。d[i]*(d + i)f1d(*d)[i].ivald[i]i

繰り返しますが、C++ を使用しているため、おそらくポインタを参照として渡したはずです。

 void f2(data_t * & d)  // <--- reference to the original pointer
 {
     // ...
     d[i].ival = i + 1;
 }

または、実際には、元のものd自体を変更することはなく、それが指すもののみを変更するため、で渡すこともできます:

void f3(data_t * d)     // <--- pointer passed by value
{
     // as before, d[i].ival etc.
}

むしろ、ポインタをまったくstd::vector<data_t>使用せずにa を使用する必要があります。(また、 のクラス定義を typedef しないでくださいdata_t。)

于 2012-04-10T05:19:21.077 に答える
1

関数f1が ** 型の引数 (つまり、配列の配列、または単なる行列) を待機しています。したがって、d[i] と書くと、それは単一の要素ではなく、配列 (行列の行) になります。そのため、どちらd[i].ivalも機能しませんd[i] -> ival。あなたにとって最良の解決策はstd::vector、STLから使用することだと思います。

于 2012-04-10T05:36:54.720 に答える