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;
}

每当在 push 中声明一个新节点时,堆栈的所有先前值中的数据都会更改。有什么我不知道的指针会导致它们随机改变值吗?

编辑:这个新代码有效:

#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

在 push 中,每次都需要创建一个新节点。

改变这个:

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 回答