C 堆栈中的推送操作出现逻辑错误
我正在以数组的形式对堆栈执行插入操作,但我的程序在输入第一个值时崩溃C 堆栈中的推送操作出现逻辑错误,c,arrays,data-structures,struct,stack,C,Arrays,Data Structures,Struct,Stack,我正在以数组的形式对堆栈执行插入操作,但我的程序在输入第一个值时崩溃 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"); } typedef结构堆栈 { int t
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");
}
typedef结构堆栈
{
int top;
int元素[20];
}
堆栈
堆栈*s;
无效推送(整数x)
{
s->top++;
如果(s->topelements[s->top]=x;}
其他的
看跌期权(“溢出”);
}
根据您当前的代码,看起来您正在使用未初始化的s
。使用单元化内存调用,这反过来可能会导致分段错误
为了防止单元化的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
}
无效推送(int x)
{
if(s)//检查's'是否已初始化。
{
s->top++;
如果(s->topelements[s->top]=x;
}
其他的
看跌期权(“溢出”);
}
其他的
//中止、返回错误或类似情况
}
注: 除了手头的问题外,还有一个隐藏的问题,在您解决此问题后,它将立即出现 在
push()
函数中,您无条件地增加top
值。这意味着,即使堆栈已满,您的top
值也将增加,稍后将导致错误计算
您还必须在值范围检查下移动堆栈
顶部
增量部分。看起来您只是定义了一个struct stack类型的指针,但没有分配堆栈本身
stack *s;
因此s等于NULL。至少您应该分配堆栈本身。例如
stack *s;
//...
s = malloc( sizeof( struct Stack ) );
stack s;
但在任何情况下都不需要定义指针。您可以定义堆栈本身。例如
stack *s;
//...
s = malloc( sizeof( struct Stack ) );
stack s;
Aldo您需要设置数据成员top的初始值。我认为您可以使用-1初始化它
此外,函数insert本身无效
void push(int x)
{
s->top++;
if(s->top<=19){
s->elements[s->top]=x;}
else
puts("Overflow");
}
无效推送(int x)
{
s->top++;
如果(s->topelements[s->top]=x;}
其他的
看跌期权(“溢出”);
}
每次调用该函数时,它都会增加数据成员top,即使它已指向数组之外
void push(int x)
{
if ( s->top + 1 < 20)
{
s->elements[++s->top] = x;
}
else
[
puts("Overflow");
}
}
无效推送(int x)
{
如果(s->top+1<20)
{
s->elements[++s->top]=x;
}
其他的
[
看跌期权(“溢出”);
}
}
检查如果(s)
有点棘手;它可以被用户释放s
-并且没有设置为NULL。因此检查将是正常的-实际上是UB@Giorgi是的,但是大多数时候,添加一个简单的空检查可以为您节省很多麻烦。:-)顺便说一句,您有什么改进建议吗?可能会告诉用户在释放后将指针设置为NULL,否则if语句将触发UB:。如果您能够确保指针不为NULL这一事实意味着指针有效,那么这些if语句是有意义的-在Linux上,这可能会更加棘手,例如malloc可能失败并返回notnull@Giorgi我完全同意。上面的信息非常有用,但我认为,在当前场景中有点脱离上下文。我们不知道free()
ing部分实现,是吗?不过,感谢您提供的有用信息。希望它能帮助某人。:-)是的,你是对的。在释放s
时调用push
也没有意义;但该检查也不会保存你。除非你在释放后将其设置为NULL。但是,malloc/Linux问题将是另一个问题