2012-04-10 24 views
1

大丈夫、これはおそらく本当にシンプルですが、ポインタ、配列、メモリ割り当てについてサイト全体を見渡しましたが、説明が少し複雑すぎます。だから...誰かが私に以下のコードの中の別のものを指している理由を説明できますか?私は何をする必要があるかけれどもポインタ、配列、および構造体(およびメモリの割り当て)?

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を有するように配列の500個の各要素を埋めるありますsval 'には配列インデックス0〜499の文字列 "$ 1" - "$ 500"が含まれています。関数呼び出しで。

も:

d = new data_t[500] 

私は構造体の500要素の配列にメモリを割り当てるために必要なすべてのですか?

ちょうどそれがポインタが何か間違った道を指しているデバッガを見て...関数呼び出しで、メインのループのために動作しますが、いない理由を把握しようと...

答えて

4

「それは動作します"mainの場合、d[i]*(d + i)と同じです。あなたが(*d)[i].ivalなどを言う必要があるので、あなたの関数f1では、dは、ポインタへのポインタである(あなたが書いたものを、d[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>を使用してはいけません。 (また、クラス定義をdata_tにtypedefしてはいけません。

+0

これはまさに問題でした... 今、私はsvalにint iを変更するつもりですか?これは間違っていますが、例です sval =( '$' + char(i + 1)+ '\ 0'); – Sun

+0

@Sun: 'char *'を 'std :: string'に変更します。 –

+1

ええ、それはうまくいくことは分かっていますが、これは実際にインタビューのためのテストです...要件とそれ以外のもの 彼らは言われて以来、私はどこかmalloc()を使用したいと確信しています... – Sun

1

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

関連する問題