从堆栈中检索项目时C程序崩溃

时间:2010-01-06 23:00:19

标签: c pointers stack

以下代码在第二次Pop()调用时崩溃。我是C的新手,我现在一直盯着这段代码超过一个小时,我看不出错误。有什么想法可以帮助我解决这个代码崩溃的原因吗?

#include <stdio.h>

#define StackDataSize 100

typedef struct Stack
{
    int index;
    void *data[StackDataSize];
} Stack;

void* Pop(Stack *s)
{
    if(s->index >= 0)
    {
        return s->data[s->index--];
    }
    else
    {
        fprintf(stderr, "ERROR: Stack Empty\n");
        return NULL;
    }
}

void Push(Stack *s, void *v)
{
    if(s->index < StackDataSize)
    {
        s->data[++s->index] = v;
    }
    else
    {
        fprintf(stderr, "ERROR: Stack Full\n");
    }
}

int main(void)
{
    Stack s = {-1}, *intstack = &s;

    int x = 123456;
    Push(intstack, &x);

    printf("%d\n", *(int*)Pop(intstack));
    printf("%d\n", *(int*)Pop(intstack));

    return 0;
}

7 个答案:

答案 0 :(得分:11)

在第二个Pop上,堆栈为空,如果堆栈为空,Pop返回NULL。

所以在第二行:

printf("%d\n", *(int*)Pop(intstack));

您正在取消引用NULL作为指向int的指针。

printf("%d\n", *(int*)NULL );

答案 1 :(得分:6)

第二个pop尝试从空堆栈弹出,Pop()函数返回NULL。然后main函数尝试取消引用这个NULL - 指针并打印它指向的值。

由于NULL指针未指向任何有效的内容,因此会出现分段错误。

答案 2 :(得分:3)

Pop的第二次调用会返回NULL,然后您将其转换为int *并尝试取消引用。取消引用NULL会导致段错误。

答案 3 :(得分:2)

要回显所有以前的答案,问题是对Pop的第二次调用返回NULL,您尝试在第二次调用printf()时取消引用。

在一个纯粹的信息性说明中,基于数组的堆栈,如果你从顶部到底部增长,而不是相反,它会更容易一些:

void Push(Stack *s, void *v)
{
  if (s->index)
    s->data[--s->index] = v;
  else
    // overflow
}

void *Pop(Stack *s)
{
  if (s->index < StackDataSize)
    return s->data[s->index++];
  else
  {
    // underflow
    return NULL;
  }
}
...
Stack s = {StackDataSize, {NULL}};

这种方式0不会成为特例。

答案 4 :(得分:1)

你试图取消引用你在空案例中返回的NULL。

答案 5 :(得分:0)

“索引”成员是签名还是未签名?如果它是无符号的,则表达式“s-&gt; index--”将导致非常大的数字。

答案 6 :(得分:0)

当我查看你的代码时,我发现另一个也会导致崩溃的问题:我认为你Push()上也有一个“一个一个”错误,在这里:

void Push(Stack *s, void *v)
{
    if(s->index < StackDataSize)
    {
        s->data[++s->index] = v;
    }
    ...

检查s->index < StackDataSize,然后执行预增量++s->index并写入s->data将在数组末尾写一个s->index == StackDataSize - 1。这也会给你一个分段错误。