【问题标题】:Values changing in C stack implementationC 堆栈实现中的值变化
【发布时间】:2013-02-11 14:37:38
【问题描述】:

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

【问题讨论】:

    标签: c pointers stack


    【解决方案1】:

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

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

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

    【讨论】:

    • 啊,非常感谢。我以前见过这样做,但现在我明白了。
    【解决方案2】:

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

    改变这个:

    struct snode newnode;
    

    到:

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

    然后将newnode. 更改为newnode-&gt;

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-27
        • 1970-01-01
        • 1970-01-01
        • 2020-09-13
        • 2016-12-16
        • 1970-01-01
        • 2010-11-26
        • 2010-12-15
        相关资源
        最近更新 更多