1

C でスタックを実装しようとしていますが、新しいデータが追加されるたびに、古い値が上書きされます。これが私のコードです:

#include <stdlib.h>

struct snode {
    int data;
    struct snode *prev;
    struct snode *next;
};

static struct snode stack;
static struct snode *stackpointer = NULL;

void push(int data) {
    if(stackpointer == NULL) {
        stack.data = data;
        stack.prev = NULL;
        stack.next = NULL;
        stackpointer = &stack;
        return;
    }

    struct snode newnode;
    newnode.data = data;
    newnode.prev = stackpointer;
    newnode.next = NULL;
    stackpointer = &newnode;
}

int pop() {
    int retdata = stackpointer->data;
    if(stackpointer->prev == NULL) {
        stackpointer = NULL; 
    }
    else {
        stackpointer = stackpointer->prev;
        stackpointer->next = NULL;
    }
    return retdata;
}

int peek() {
    return stackpointer->data;
}

新しいノードがプッシュで宣言されるたびに、データはスタックの以前のすべての値で変更されます。値をランダムに変更するポインターについて私が知らないことはありますか?

編集:この新しいコードは機能します:

#include <stdlib.h>

struct snode {
    int data;
    struct snode *prev;
    struct snode *next;
};

static struct snode *stackpointer = NULL;

void push(int data) {
    struct snode *newnode = (struct snode*)malloc(sizeof(struct snode));
    newnode->data = data;
    newnode->prev = stackpointer;
    newnode->next = NULL;
    stackpointer = newnode;
}

int pop() {
    int retdata = stackpointer->data;
    if(stackpointer->prev != NULL) {
        stackpointer = stackpointer->prev;
        free(stackpointer->next);
    }
    else {
        free(stackpointer);
        stackpointer = NULL;
    }

    return retdata;
}

int peek() {
    return stackpointer->data;
}
4

3 に答える 3

4

push()関数では、stackpointerローカル変数のアドレスが割り当てられています。関数が戻った後はstackpointer、ダングリング ポインターにnewnodeなり、有効ではなくなります。以下を使用して、スタックに新しいノードを動的に割り当てますmalloc()

struct snode* newnode = malloc(sizeof(*newnode));

push()への最初の呼び出しで が のstackpointerアドレスに割り当てられるため、スタック内の要素のストレージを混在させないでくださいstack。スタックを正しく実装するには、ノードを動的に割り当てる必要がありますfree()stacktoのアドレスを渡すことfree()は無効です。複雑さを避けるために、スタックの使用法を一貫して保ちます。常に動的にノードを割り当て、常にノードを解放してください。

于 2013-02-11T14:41:47.077 に答える
1

プッシュでは、毎回新しいノードを作成する必要があります。

これを変える:

struct snode newnode;

に:

struct snode *newnode = malloc(sizeof(struct snode)); 

次に、に変更newnode.newnode->ます。

現状では、変数newnodeは関数内にのみ存在しますpush-たまたま、それがひどく上書きされることはありません。または、「呼び出したときにプログラムが奇妙にクラッシュするのはなぜですか。そして、の同じ関数から呼び出されてpop()いる限り、pushコードでは、スタック上の同じ場所を使用するため、スタックに別のアイテムを追加するたびに、スタック上の同じ(まもなく「未使用」)場所に保持されている古い値が上書きされます。

于 2013-02-11T14:43:26.540 に答える
0

malloc新しいノードを割り当てるためにを使用する必要があります。あなたはそれを内部pushで作成しているだけで、次にpush(または他のルーチン)が呼び出されたときにそれが壊れるでしょう。

ちなみに、nextポインタは必要ありません。必要なのは。だけprevです。

于 2013-02-11T14:43:16.003 に答える