0

以下を持って、

struct node{
    int value;
    struct node *next;
};

typedef struct node Node;
typedef struct node *pNode;

Node newNode(){
    Node n;
    n.value = 5;
    return n;
}

pNode newpNode(){
    pNode pn = (pNode) malloc(sizeof(Node));
    pn->value = 6;
    return pn;
}

メモリの割り当て解除が呼び出し元関数によって行われる場合は newpNode() を使用し、それ以外の場合は newNode() を使用する必要があることをどこかで読みましたが、それでは十分に理解できません。

newNode() と newpNode() をいつ使用する必要があるかについて、具体的な例をいくつか教えてください。

編集: newpNode() 内で pn を忘れた

4

1 に答える 1

2

この単純な例では、どちらか一方を使用する必要はありません。

newNode() を呼び出すと、関数が呼び出されたときにメモリが割り当てられ、呼び出しから (呼び出しスタックに) 返される Node のサイズが格納されます。このメモリは変数に割り当てることができ、それを維持します (コール スタックのメモリはローカル変数に memcpy されます)。

Node n = newNode();

ただし、ノードが複雑になると、問題が発生します。たとえば、ネストされたデータ構造がある場合、これらは一緒にコピーされず、newNode() がクリーンアップするときに破棄される可能性があります。

また、Node に必要なメモリが大きくなる (つまり、フィールドが増える) と、これらの呼び出しを行うためにスタック上でより多くのメモリが必要になります。これは、再帰や一般的な効率などを制限する可能性があります。

これらの制限に対処するには、newPNode() でヒープにメモリを割り当てます。これは、Node のサイズに関係なく、常にポインターを返します。ただし、後でこのメモリを明示的にクリーンアップする必要があります。そうしないと、メモリ リークが発生します。

于 2013-05-07T03:55:36.587 に答える