学习途中遇到的segmentation fault之二——&&与栈

来源:互联网 发布:plc程序c语言 编辑:程序博客网 时间:2024/05/16 08:54

这是数据与结构中的一个例子,这本书的例子有很多错误,虽然可能新版书可能会改正错误,但是这里的错误非常典型,我们从中会学到很多东西!下面是我已经修改好的例子:

#include <stdio.h>#include <stdlib.h>struct s_node{int data;struct s_node *next;};typedef struct s_node s_list;typedef s_list *link;link operator=NULL;link operand=NULL;link push(link stack,int value){link newnode;newnode=(link)malloc(sizeof(s_list));if(!newnode){printf("Memory allocation failure!!!");return NULL;}newnode->data=value;newnode->next=stack;stack=newnode;return stack;}link pop(link stack,int *value){link top;if(stack!=NULL){top=stack;stack=stack->next;*value=top->data;free(top);return stack;}else*value=-1;}int empty(link stack){if(stack==NULL)return 1;elsereturn 0;}int is_operator(char operator){switch(operator){case '+': case '-': case '*': case '/': return 1;default: return 0;}}int priority(char operator){switch(operator){case '+': case '-': return 1;case '*': case '/': return 2;default: return 0;}}int two_result(char operator,int operand1,int operand2){switch(operator){case '+': return (operand2+operand1);case '-': return (operand2-operand1);case '*': return (operand2*operand1);case '/': return (operand2/operand1);}}void main(){char expression[50];int position=0;int op=0;int operand1=0;int operand2=0;int evaluate=0;printf("\nPlease input the iorder expression:");gets(expression);while(expression[position]!='\0' && expression[position]!='\n'){if(is_operator(expression[position])){if(!empty(operator))while(!empty(operator)&&priority(expression[position])<=priority(operator->data)){operand=pop(operand,&operand1);operand=pop(operand,&operand2);operator=pop(operator,&op);operand=push(operand,two_result(op,operand1,operand2));}operator=push(operator,expression[position]);}elseoperand=push(operand,expression[position]-48);position++;}while(!empty(operator)){operator=pop(operator,&op);operand=pop(operand,&operand1);operand=pop(operand,&operand2);operand=push(operand,two_result(op,operand1,operand2));}operand=pop(operand,&evaluate);printf("The exoression [%s] result is '%d'\n",expression,evaluate );}


辛苦了,看了这么长的代码!下面且让我慢慢道来书中的例子与我修改后的例子的不同!

        while(!empty(operator)&&priority(expression[position])<=priority(operator->data))相信很多人会在这出现segmentation fault,因为原书是将&&两边的语句反过来放置的,即执行时会先判断priority(expression[position])<=priority(operator->data),但会造成什么问题呢?

如果我们执行2*3-1时,最后

while(!empty(operator)&&priority(expression[position])<=priority(operator->data)){operand=pop(operand,&operand1);operand=pop(operand,&operand2);operator=pop(operator,&op);operand=push(operand,two_result(op,operand1,operand2));}


会最后执行一次跳出循环,但是在判断priority(expression[position])<=priority(operator->data)时,就会出现错误,此时元算符栈为空,operator->data没有目标当然会造成错误,所以让人抓狂的segmentation fault出现了。

但是如果改成我的例子当中写的先检验,先执行!empty(operator),检验元素符栈是否为空,若为空则其值为0,则不会执行&&后面的语句,从而避开空目标的问题,巧妙的避开了segmentation fault。

从中我们可以看到,有时候只是简单的换下语句的顺序会起到意想不到的作用啊!