C堆栈实现中的值更改

时间:2013-02-11 14:37:38

标签: c pointers stack

我正在尝试在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;
}

3 个答案:

答案 0 :(得分:4)

push()函数stackpointer中分配了一个局部变量的地址。函数返回后stackpointer将是一个悬空指针,因为newnode将不再有效。使用malloc()动态分配堆栈的新节点:

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

请勿在第一次调用push()时混合堆栈中元素的存储,stackpointer被分配到stack的地址。要正确实现堆栈,您需要动态分配您还必须free()的节点。将stack的地址传递给free()无效。保持堆栈的使用一致以避免复杂化:始终动态分配节点并始终释放节点。

答案 1 :(得分:1)

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

CHange this:

struct snode newnode;

为:

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

然后将newnode.更改为newnode->

就目前而言,变量newnode仅存在于函数push中 - 因为它发生了,它永远不会被严重覆盖,或者你的问题是“为什么我的程序在我打电话时奇怪地崩溃pop()。只要从代码中的同一个函数调用push,它就会在堆栈中使用相同的位置,所以每次将另一个项添加到堆栈时,它都会覆盖旧的值保持在堆栈中的相同(即将被“未使用”)位置。

答案 2 :(得分:0)

您需要使用malloc来分配新节点。 您只是在push内创建它,并且在下次调用push(或任何其他例程)时它将被破坏。

顺便说一句,您不需要next指针,只需要prev