リンクリスト内のノードの動的メモリ割り当て
ノード(ヘッド)へのポインタを宣言する必要があるのに、それを使用して、またはノードにメモリを割り当てるmalloc
必要calloc
があるのはなぜですか?リストを生成するコード(ここではインポートされません)は、メモリを割り当てずに、を宣言するだけでもうまく機能することがわかりましたnode *head
。
typedef struct str_node{
int data;
struct str_node *next;
}node;
int main(){
node *head;
head = (node*) malloc(sizeof(node));
head = NULL;
そして、なぜ私が上記のようにメモリを割り当てるとき、私は書かなければならないの(node*)
ですか?頭上でやっているので、すでに構造体ノードに割り当てられていませんか?そのコード行の正確な意味は何ですか?さらに、私が書くとき、私head = NULL
はポインタヘッドのアドレスをNULLに設定しますか?
回答
このコードスニペット
node *head;
head = (node*) malloc(sizeof(node));
head = NULL;
メモリリークが発生します。
最初に、node
そのタイプのオブジェクトのメモリが割り当てられ、そのアドレスがポインタに割り当てられました。head
head = (node*) malloc(sizeof(node));
そしてすぐにポインタの値が上書きされました。
head = NULL;
その結果、割り当てられたメモリのアドレスが失われ、割り当てられたメモリを解放できません。
コードスニペットは意味がありません。書くだけで十分でしょう
node *head = NULL;
この場合、最初は空のリストになります。
そして、なぜ私が上記のようにメモリを割り当てるとき、私は(ノード*)を書かなければならないのですか?
この関数malloc
は、タイプのポインタを返しますvoid *
。このタイプvoid *
のポインタは、他のオブジェクトタイプのポインタに割り当てることができます。したがって、Cではキャストは冗長です。
C ++ではvoid *
、型のポインタvoid *
が割り当てられているオブジェクトポインタの型に型のポインタを明示的にキャストする必要があります。
さらに、head = NULLと書くと、ポインタヘッドのアドレスをNULLに設定しますか?
ポインタ自体のアドレスを設定していません。ポインターはコンパイラーによって割り当てられ、自動保存期間があります。head
タイプnode *
を持つ変数の値をNULLに設定します。
Cでは、ポインターは整数と同じように値です。あなたが書くとき:
int a;
a = 3;
値3を変数に格納しますa
。
あなたが書くとき:
int* p;
p = NULL;
値NULL
を変数に格納しますp
。ポインタについて特別なことは何もありません。割り当ては、の値p
、つまり何を指しているのか、何を指しているのかにはまったく依存しません。(この場合、それは何も指していませんが、それは無関係です。)
malloc
上で説明したように値であるメモリ領域へのポインタを返します。ポインタには固有のメタデータはありません。malloc
メモリ領域のサイズを超える情報は必要ありません。特に、メモリ領域が何に使用されるかを知りません(または気にしません)。その値が生成されたら、次に適切と思われるように処理できます。
int* p;
p = malloc(sizeof *p);
ためp
のポインタとして宣言されint
、メモリによって指し示さことが期待されているp
保持することができますint
。(まだですが、可能です。)しかし、ポインタが指すメモリに格納されている整数(存在する場合)に影響を与えることなく、ポインタを(値として)渡すことができます。たとえば、後
int* q = p;
q
p
同じメモリをポイントします。
この混乱のいずれかを見つけた場合、それはおそらく、ポインタが単純な値以外のものであると期待しているためです。ただし、それらは単純な値であり、その単純な現実に基づいたメンタルモデルが必要です。