2

私は以下のような構造を持っています

typedef struct Mystruct{
char *name;
int telno;
struct Mystruct *nextp;
}data;

今、私は構造をmallocします

data *addnode;
addnode = malloc (sizeof(data));

にデータを追加しますchar *name

addnode->name = malloc (sizeof(MAX));

質問malloc:なぜ再度必要なのですか?

malloc私は-ingaddnodeがメモリを割り当てることさえあると仮定していましaddnode->nameたが、そうではありません。

4

3 に答える 3

3

malloc深くなく、再帰を行いません。したがって、渡す構造体内のポインターにはメモリが割り当てられません。

これについてもう少し考えてみると、そうでなければならないことがわかります。割り当てている構造に関する情報は渡さないでください。メモリ ブロックのサイズを渡すだけです。今、mallocあなたが割り当てているデータのタイプさえ知りません。ブロック自体にポインターが含まれていることはわかりません。

この設計上の選択がなされた理由については、ポインタが参照するメモリの所有者をライブラリがどのように判断できるのでしょうか? おそらくそれはその構造によって所有されています。または、そのポインタを使用して、別の場所に割り当てられたメモリを参照したい場合もあります。それを知ることができるのはあなただけです。実際、あなたの構造はこれの良い例です。おそらくnameメンバーは構造によって所有されていますが、nextpメンバーはそうではありません。

于 2012-12-10T11:36:19.350 に答える
2

にメモリを割り当てるMystructと、 へのポインタに十分なメモリが提供されますname。この時点では、名前に含まれる文字数がわからないため、名前にメモリを割り当てることはできません。

単一の割り当てで構造を完全に割り当てたい場合は、最大サイズを決定しname、構造定義を次のように変更できます。

#define MAX_NAME (10) /* change this as required */
typedef struct Mystruct{
    char name[MAX_NAME];
    int telno;
    struct Mystruct *nextp;
}data;

または、構造体を割り当てるときに名前がわかっている場合は、コンストラクター関数を提供することで、呼び出し元から 2 つの割り当ての必要性を隠すことができます。

struct Mystruct* Mystruct_create(const char* name)
{
    Mystruct* ms = malloc(sizeof(*ms));
    ms->name = strdup(name);
    return ms;
}
于 2012-12-10T11:36:01.080 に答える
1

いいえ、最初malloc()に名前へのポインタを保持するためのメモリを含む構造体全体にメモリを割り当てます。つまり、32 ビット OS では 4 バイトです。

データを保持するためにメモリを個別に割り当てる必要があります。デフォルトでは、初期化されていない場合、そのポインターはガベージの場所を指しています。

free()あまりにも同じケース。つまり、最初に内部ブロックを解放してから、構造全体のメモリを解放する必要があります。には再帰的なものはありませんmalloc() and free()

于 2012-12-10T11:34:51.123 に答える