リンクリスト内のノードの動的メモリ割り当て

Aug 20 2020

ノード(ヘッド)へのポインタを宣言する必要があるのに、それを使用して、またはノードにメモリを割り当てる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に設定しますか?

回答

2 VladfromMoscow Aug 19 2020 at 23:35

このコードスニペット

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に設定します。

2 rici Aug 19 2020 at 23:43

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;

qp同じメモリをポイントします。

この混乱のいずれかを見つけた場合、それはおそらく、ポインタが単純な値以外のものであると期待しているためです。ただし、それらは単純な値であり、その単純な現実に基づいたメンタルモデルが必要です。