我目前正在研究数据结构和算法,并学习堆栈的工作原理。
我编写了一个简单的 C 代码,展示了堆栈的基本功能如何工作,包括
push
和 pop
算法,它们基本上将元素处理成数组。代码尚未完成,我正在努力学习该语言及其算法。令我惊讶的是,我在编译后收到了一个错误'segmentation fault (core dumped)'
,这对于我这个正在学习如何编码的人来说非常困惑。
#include <stdio.h>
#include <string.h>
#define MAXSIZE 100
struct stack
{
int a[MAXSIZE];
int Top;
};
/*
* Add an element to stack
*/
void push(struct stack *pu)
{
int element;
printf("element: ");
scanf(" %d", &element);
pu->a[pu->Top] = element;
if(pu->a[pu->Top] >= MAXSIZE -1)
{
printf("stack is full\n");
} else{
// Prints out the top most element
printf("Top is: %d\n", pu->a[pu->Top]);
}
}
/*
* Pop/Remove an element from the stack
*/
void pop(struct stack *po)
{
printf("You're in pop function.\n");
if(po->Top <= -1)
{
printf("stack is underflow");
} else{
printf("%d will be remove from the stack", po->a[po->Top]);
printf("%d has been removed from the stack", po->a[po->Top]);
}
}
void Second(char x[])
{
struct stack pa;
if(x[1] == 'u')
{
push(&pa);
} else if(x[1] == 'o'){
pop(&pa);
}
}
int main()
{
int element;
char s[MAXSIZE];
struct stack ps;
ps.Top = -1;
printf("Push or Pop?\n");
scanf("%s", &s);
Second(s);
}
要具体回答您的问题,问题出在函数
void Second(char[])
中:您没有初始化struct stack pa
。 pa.Top
采用一些不可预测的值,很可能太大,并且当您执行push
时,您尝试访问未在pu->a[pu->Top] = element;
中保留的内存空间。尝试访问进程未保留的内存地址会导致分段错误 (segfault)。
执行
pa->a[99999] = whatever
也可能会出现段错误,因为 pa->a
的大小为代码片段中定义的 100
。
当声明变量或结构(例如堆栈)时,您只是声明您将需要内存来使用该对象。但是,您并没有特别要求该内存充满有意义的值。通常,这意味着结构体是使用之前使用时内存中已存在的任何数据来设置的。这就是为什么您应该尽快将结构体的字段设置为已知值。如何做到这一点是风格问题,我通常会创建一个专用于名为
mystruct_ctor
(对于构造函数)的函数,或者只是使用 struct stack pa = {0}
将所有内容设置为零。