【问题标题】:C linked list won't change when I push data onto an initialised stack当我将数据推送到初始化堆栈时,C 链表不会改变
【发布时间】:2017-03-31 16:43:16
【问题描述】:

我正在尝试使用 C 中的链表来实现堆栈,但是每当我在将新值压入堆栈后尝试调用该值时,都会出现段错误。我知道这种情况正在发生,因为即使我添加了堆栈,程序仍然说堆栈为空。由于某种原因,我在推送中所做的更改在函数终止时不会保留,我无法弄清楚原因。

这是我的堆栈结构、初始化和推送代码:

typedef struct stack
{
    int value;
    struct stack * next;
} * stack_T;

stack_T
new_stack()
{
    return NULL;
}

int
push_stack(stack_T s, int data)
{
    stack_T new = malloc(sizeof(stack_T));
    new = s;
    if (s == NULL)
    {
        s = malloc(sizeof(stack_T));
        if (s == NULL)
            return 1;
    }
    s->value = data;
    s->next = new;
    return 0;
}

编辑:感谢您的帮助,但我忘了提及必须使用这些参数来完成推送,这是分配的一部分。我不是在寻找如何去做,而是在寻找我做错了什么。我知道我可以通过引用来模拟传递,但正如我所说,它必须是:

int push_stack(stack_T s, int data)

我以前用这种风格制作过结构,并且有函数将它们作为参数并保留更改,但在这种情况下它们不会,我不知道为什么。

【问题讨论】:

  • 您通常不应该创建指针的类型别名,例如stack_T。这是因为malloc(sizeof(stack_T)) 为指针分配了足够的空间,而不是结构。
  • 您还应该花一些时间搜索和阅读有关在 c 中通过引用模拟调用
  • 您还 malloc 一个堆栈,但随后覆盖下一行中的唯一引用....您应该画出什么指向什么的图片,然后遍历您的代码...有一堆错误...
  • 我建议避免使用“new”作为变量名。它在 C 中是合法的,但在 C++ 中是保留字,以后可能会给您带来麻烦。
  • 与问题更相关,我建议您为类型、函数和函数实现编写 documentation(即在 cmets 中)。这些应该足以证明(在非正式意义上)您的代码是正确的。由于您的代码实际上是错误的,因此这个过程不仅应该帮助您发现问题所在,而且应该清楚如何改正。

标签: c struct linked-list stack push


【解决方案1】:

您似乎没有将s 标记为双指针。看起来您正试图推入链接列表的前面。您需要将引用的双指针传递到堆栈的头部,以更改存储在内存中的地址值。这样,您将始终引用堆栈的顶部。

int
push_stack(stack_T **s, int data)
{
    stack_T *new = malloc(sizeof(stack_T));
    if (new == NULL)
        return (1);
    if (s == NULL)
    {
        free(new);
        return (1);
    }
    new->value = data;
    new->next = *s;
    *s = new;
    return 0;
}

我必须看看你的 main 函数是如何被调用的,这会导致段错误。但是,您似乎没有对堆栈顶部的正确引用。另外,我不太明白为什么您要为两个节点分配空间。 Malloc 返回一个指针,该指针由您指定的大小声明。

你在这里写的:

stack_T new = malloc(sizeof(stack_T));
new = s;
if (s == NULL)
    {
        s = malloc(sizeof(stack_T));
        if (s == NULL)
            return 1;
    }

永远不会遇到 NULL 是一种 void 指针类型,而您分配的 s 不是指针类型,因此当 malloc 返回 8 个字节的指针时,您试图存储 12 个字节的变量。

还有一个提示是您可以使用gcc -g 进行编译并使用valgrind 来确定发生段错误的行

【讨论】:

  • 不,你错过了stack_T已经是一个指针类型,所以stack_T *确实是一个双指针。 OP 将其隐藏在 typedef 后面的粗鲁,真的。
  • S 被初始化为 NULL,因此它在第一次检查中可以为 NULL,而第二次检查的原因是(罕见的)malloc 找不到内存,无论出于何种原因它都会返回 NULL。正如约翰所说, stack_T 已经是一个指针。不过感谢您的帮助。
猜你喜欢
  • 2016-04-18
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 2023-04-09
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多