【问题标题】:Logical error in push operation in stack堆栈中的推送操作中的逻辑错误
【发布时间】:2015-05-26 11:20:23
【问题描述】:

我正在将堆栈作为数组进行插入操作,但我的程序在输入第一个值时崩溃。

typedef struct Stack
{
  int top;
  int elements[20];
}
stack;
stack *s;

void push(int x)
{
  s->top++;
  if(s->top<=19){
  s->elements[s->top]=x;}
  else
    puts("Overflow");
}

【问题讨论】:

    标签: c arrays data-structures struct stack


    【解决方案1】:

    根据您当前的代码,您使用的似乎是 s 未初始化。使用未初始化的内存会调用 undefined behaviour,而这又可能导致分段错误。

    为了防止统一化 s ,您可能需要修改您的代码,例如

    void push(int x)
    {
      if (s)         //check if `s` has been initialized.
      {
          s->top++;
          if(s->top<=19)
          {
              s->elements[s->top]=x;
          }
          else
              puts("Overflow");
      }
      else
          //abort, return error or something similar
    }
    

    注意:

    除了这里的问题,还有一个隐藏的问题,一旦你解决了这个问题就会出现。

    在您的push() 函数中,您无条件地递增top 值。这意味着,即使堆栈已满,您的 top 值也会增加,然后会导致计算错误。

    您还必须在值范围检查下移动堆栈top 增量部分。

    【讨论】:

    • 检查if (s) 有点棘手;它可以被用户释放s-并且没有设置为NULL。因此,该检查将没问题 - 实际上它将是 UB
    • @Giorgi 是的,但是大多数的时候,添加一个 simple 空检查可以省去很多麻烦。 :-) 顺便说一句,你有什么改进建议吗?
    • 可能会告诉用户释放后将指针设置为NULL,否则if语句将触发UB:stackoverflow.com/questions/26704344/…。如果您可以确保指针不是 NULL 的事实意味着指针是有效的,那么这些 if 语句是有意义的 - 这在 Linux 上可能会更加棘手,例如 malloc 可能会失败并返回 not null
    • @Giorgi 我完全同意。上面的信息非常有帮助,但恕我直言,在当前情况下有点脱离上下文。我们对free()ing 部分的实现一无所知,是吗?不过,感谢您提供有用的信息。希望它会帮助某人。 :-)
    • 是的,你是对的。此外,在释放的s 上调用push 也是没有意义的;但那张支票也救不了你。除非您在释放后将其设置为 NULL。但是那个 malloc/Linux 问题将是一个单独的问题
    【解决方案2】:

    您似乎只是定义了一个 struct Stack 类型的指针,但没有分配堆栈本身

    stack *s;
    

    因此 s 等于 NULL。至少你应该分配堆栈本身。例如

    stack *s;
    
    //...
    s = malloc( sizeof( struct Stack ) );
    

    但是在任何情况下都不需要定义一个指针。您可以定义堆栈本身。例如

    stack s;
    

    您是否需要设置数据成员顶部的初始值。我认为您可以使用 -1 对其进行初始化。

    函数insert本身也是无效的。

    void push(int x)
    {
      s->top++;
      if(s->top<=19){
      s->elements[s->top]=x;}
      else
        puts("Overflow");
    }
    

    每次调用该函数时,它都会增加数据成员顶部,即使它已经指向数组之外。有效的函数可能看起来像

    void push(int x)
    {
       if ( s->top + 1 < 20)
       {
          s->elements[++s->top] = x;
       }
       else
       [
           puts("Overflow");
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 2018-06-12
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 1970-01-01
      相关资源
      最近更新 更多