2016-12-11 7 views
-1

私はプログラミングCの初心者であり、構造の動的配列を作成するときに値を取得して設定する際に助けが必要です。動的に割り当てられた配列の配列の値を取得して設定する

Iは、例えば、この構造体を有する:

struct opt{ 
    int size; 
    Element* elements; 
    CopyFunction copyElement; 
}; 
typedef struct opt * Popt; 

私は動的割り当てを使用して、タイプstruct optの5つの構造体のためのメモリを割り当てmallocを使用します。私はこの行を使用しました:

Popt opt_t = (Popt)malloc(5*sizeof(struct opt)); 

これらの構造体の値を取得して設定します。

opt_t [2] .size、opt_t [3] .elementsを、opt_t [3]

を.copyElement:私はOOPのようなことを考えるならば、私はこのような値を取得したいと思いどのように私はCでそれを行うことができますか?私は次の行とその悪い見た目を使用しようとしました(私の記憶はゴミでいっぱいでした)。

*((&(opt_t->size)+(2*sizeof(struct opt)))) 
*((&(opt_t->elements)+(3*sizeof(struct opt)))) 
*((&(opt_t->copyElement)+(3*sizeof(struct opt)))) 
+1

'_t'という接尾辞は、型名(C標準の' size_t'、 'uint8_t'、' wchar_t'などと思っています。変数に接尾辞を使用しない方がいいでしょう。コードを読んでいる人を混乱させる可能性があります。実際に間違っているわけではありません。多くのCコードを見た人に間違ったメッセージを送ります。 –

+0

も参照してください[typedefポインタには良いアイデアです](http://stackoverflow.com/questions/750178/is-it-a-good-ide-to-typedef-pointers) - 簡潔な答えは "いいえ"です。 。 –

答えて

2

:最後空きメモリで

Popt *opt_t; 

//do error checking of the return value of malloc 
opt_t = malloc(5 * sizeof(opt_t)); //5 pointers 
for(i = 0; i < 5; i++){ 
    opt_t[i] = malloc(sizeof(opt)); //each struct 
} 

を:

opt_t[2].size, opt_t[3].elements, opt_t[3].copyElement 

Cでどうすればいいですか? 'OOP' で

同様:

opt_t[2].size 
opt_t[3].elements 
opt_t[3].copyElement 

は、あなたがそれを試してみましたか?何が悪かったのか? *((&(opt_t->size)+(2*sizeof(struct opt))))のような表記は、間違った方向に完全に進んでいるので、通常のCではオブジェクトのサイズでポインタを拡大縮小する必要はありません。彼らが何をしているのか解読することは可能ですが、意図したものではなく、割り当てられた範囲外のメモリにアクセスすることによって未定義の動作を呼び出します。 (あなたが本当に彼らが何を知りたい場合は、コメントを残して、私は言えますが、あなたは彼らがあなたのコメントに行う考えを説明する必要があります。)

をあなたは、あなたが使用することができますしたい場合:

(*(opt_t + 3)).copyElement 

ポインタのインデックスを作成し、参照を解除して、メンバアクセスを適用します。しかし、代わりにopt_t[3].copyElementを使用する方が簡単です。また


、私はtwocommentsで述べたように:

  1. _tサフィックスが最も一般的にタイプ名を示すために使用されることに注意してください(C標準からsize_tuint8_twchar_tなどを考えますPOSIXからの多くのもの)。変数に接尾辞を使用しない方がいいでしょう。コードを読んでいる人を混乱させる可能性があります。実際に間違っているわけではありません。多くのCコードを見た人に間違ったメッセージを送ります。

  2. Is it a good idea to typedef pointersも参照してください。簡潔な回答は「いいえ」(または「通常はいいえ」)です。この質問に対する回答で示されているように、そのようなtypedefは混乱を招く可能性があります。


それはまた、問題のメモリ割り当てに関するいくつかの混乱が可能性があることをsuggestedてきました。それが言うので:

私は動的割り当てを使用し、タイプ struct optの5つの構造体のメモリを割り当てるために mallocを使用したい

...

かつ迅速とはいえ、まさにそれを行うための許容可能な方法を実証するために進んで多くの人が軽蔑しているが、他の人たちを怒らせるような気にならない程度に私を心配していないcastだから、私はさらにメモリ割り当てについてコメントする必要はない。私は静かにコードが割り当てられたスペースで終了したときにfree(opt_t)または相当の場所にコールがあると仮定しています。そして、elementsメンバーに割り当てられたスペースがある場合、そのスペースが最初に解放されます。

+0

識別子名の貧弱な選択についてコメントしたいと思うかもしれません: 'opt_t'は変数ではなくタイプの名前を付けるために使われます。 'Popt'ポインタ' typedef'は遅かれ早かれ問題を引き起こします。 OPが 'malloc()'が初期化されていないメモリを返すことを知っているかどうかは明らかではありません。 – chqrlie

0

あなたは二重のポインタが必要です。私はOOPのようなことを考えるならば、私はこれらの値を取得したいと思い

for(i = 0; i < 5; i++){ 
    free(opt_t[i]); 
} 
free(opt_t); 
+0

なぜダブルポインタが必要ですか? –

+0

それぞれの 'Popt'の中のすべてのポインタとそれらが指しているものを自由にしなければならないかもしれないことを忘れないでください。 'Popt'構造体を' Popt_new'と 'Popt_free'に割り当て、解放することをカプセル化することが賢明です。 'calloc'を使うと良いでしょう。あなたはmallocから割り当てられたポインタとゴミの違いを知ることができます。 – Schwern

+0

@JonathanLeffler質問は*動的に*メモリを割り当てることでした。あなたは* 5 *を* Popt opt_t [5] *の代わりに* 5 *に変更することができます@ –

関連する問題