2016-09-27 4 views
1

この状況でメモリを2回割り当てなければならないのだろうかと思います。 は、例えば: は、私は構造体を持っていることを考慮してください。Cで別の構造体へのポインタをMallocing

struct ErrorCheck { 
    int returnValue; 
    struct Nodes * list; 
}; 

struct Nodes { 
    char * name; 
    int grade; 
    struct Nodes * next; 
}; 

し、それらをmallocを機能:上記のように

void buildList() { 
    struct ErrorCheck * newStruct; 
    newStruct = malloc(sizeof(struct ErrorCheck)); 
    newStruct->list = malloc(sizeof(struct Nodes)); 

} 

は、私が二回をmallocする必要がありますか?または両方の構造体を使いたい場合は、最初のmallocで十分です。

実際にはnewStruct = malloc(sizeof(struct ErrorCheck));で十分ですが、いずれの場合も真または偽の場合がありますか?

+1

考えてみましょう:あなたは** 2つの**オブジェクトにアクセスする必要があります。したがって、** one **オブジェクトを十分に割り当てることはできますか?私はそうは思わない。 – Olaf

+1

1つのmallocだけを使用することは技術的に可能ですが、それは多くの努力と複雑さの価値がありません –

+0

注: 'newStruct-> list = malloc(sizeof(struct Nodes))の後、' newStruct-> list - >次に(および他のメンバー)はまだユニット化されていません。 ' – wildplasser

答えて

4

これは実際にはlistで何をしたいかによって異なります。

  • あなたはlistがあなたからの読み取りと書き込みができるそれ自身のメモリを搭載したスタンドアロン変数として機能させたい場合は、あなたが二malloc()を必要とすることがあります。

  • あなたはlistは、例えば、プレースホルダのように振る舞うことにいくつかの他の既に割り当てられたポインタを割り当て、その場合には、それを使用したい場合は、 `` malloc関数を必要としません()。

malloc()sizeof(struct ErrorCheck)ため-ingとnewStructへのポインタを保存するには、あなたのメンバ変数自身のための十分なメモリを与える、すなわち、それは、intstruct node *メンバ変数のためのメモリを割り当てます。ポインタが指すメモリアドレスは不定です。意味のあるどこかを指すように、ポインタ変数にメモリを別に割り当てる必要があります。言っ

  • あなたが常に返されたポインタを使用する前にmalloc()の成功のためにチェックする必要があります。
  • するごとにfree()に電話する必要があります。
+0

"上記のように2回mallocする必要がありますか?最初のmallocで十分ですか?**両方の構造体を使用する場合は**です。 - Occamのカミソリ... – Olaf

+0

私は確かにリストに書きたいので、前者がそれであるようです。 – efefefef

+3

@Olaf _use_は非常に明確な声明ではないので、混乱を避けるために両方のシナリオを説明してみました。 :) –

0

2つのmallocが必要です。 mallocは、構造体のメンバにのみメモリを割り当てます。あなたの例では、最初のmallocは2つの8バイトのポインタと整数のためのメモリを割り当てます。ノード構造は自動的に割り当てられません。

+2

"mallocは構造体のメンバにのみメモリを割り当てます。" - いいえ。メンバーだけでなく、 'struct'型のオブジェクトのためのメモリのブロックを割り当てます(どのように動作しますか?)。ポインタに8バイトのインジケータはありません。それはそのレベルでは無関係です。実装の詳細を不必要に混ぜてはいけません。 – Olaf

1

ここにはいくつかのことがあります。

errorCheck構造体へのポインタを、buildList関数が返った後に消えるローカル変数以外のもので保持したほうがよいでしょう。関数から呼び出し元に戻し、より永続的な場所(グローバル変数または 'main'のローカル変数)に格納することもできます。リスト変数をすぐに割り当てる必要はありませんが、NULLに初期化することをお勧めします。次に、次のポインタを割り当て、その内容(名前、グレード、NULL)を設定して、ノードを追加する別の関数を使用します。

後で、ノードのチェーンをステップ実行して、ノードの一覧を表示したり、実行したら1つずつ解放したりすることができます。リストを解放することは、新しいcコーダーにとっては少し難しいかもしれません。それは別の質問です。

関連する問題