Luker 发表于 2018-12-23 17:13:17

一个调试过程中的错误,请各位热心鱼油看一下

本帖最后由 Luker 于 2018-12-24 18:34 编辑

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define STACKINCREMENT 10   //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'

typedef char ElemType;
typedef struct                  //栈的结构体
{
        ElemType *bottom;         //栈底指针
        ElemType *top;                                //栈顶指针
        int stackSize;                                //栈的大小
}sqStack;

void InitStack(sqStack *s);          //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s,ElemType e);       //入栈
void Pop(sqStack *s,ElemType *e);       //出栈       
int StackLen(sqStack *s);                       //返回栈的当前容量
void Cleanup(sqStack *s);                       //清空栈       

int main(void)
{
        sqStack s;                       
        ElemType end,c,e;
        int first,second;
        printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
        scanf("%c",&c);                               
        while(c!='\n')                                //判断输入是否为结束计算的标识
        {
                if(c==addition || c==division || c==subtraction ||c==multiplication)   //当输入为这四个运算符中的其中一个时
                {
                        Pop(&s,&e);         //出栈并将其值赋给second
                        second=e-'0';               
                        Pop(&s,&e);         //出栈并将其值赋给first
                        first=e-'0';
                        if(c==addition)   //加法运算
                        {
                                end=first+second+48;
                        }
                        if(c==division)                //除法运算
                        {
                                end=first/second+48;
                        }
                        if(c==subtraction)        //减法运算
                        {
                                end=first-second+48;
                        }
                        if(c==multiplication)        //乘法运算
                        {
                                end=first*second+48;
                        }
                        Push(&s,end);                        //将运算的结果压入栈中
                }
                else
                {
                        Push(&s,c);                                //压栈
                }
                scanf("%c",&c);                           //获取下一个输入
        }
        Pop(&s,&e);                                                //出栈
        printf("计算结果:%d",e-'0');        //显示最后的结果
        Cleanup(&s);                                        //清空栈
        return 0;       
}

void InitStack(sqStack *s)
{
        s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
        if(!s->bottom)       //申请失败时
        {
                exit(0);
        }
        s->top=s->bottom;
        s->stackSize=STACKINCREMENT;
}

void Push(sqStack *s,ElemType e)
{
        if(s->top-s->bottom>=s->stackSize)          //若栈已满
        {
                s->bottom=(ElemType *)realloc(s->bottom,(s->stackSize+STACKINCREMENT)*sizeof(ElemType)); //增加栈的容量
                if(!s->bottom)                                //申请失败时
                {
                        exit(0);
                }
        }
        *(++s->top)=e;
}

void Pop(sqStack *s,ElemType *e)
{
        if(s->top==s->bottom)                                //栈为空时
        {
                exit(0);
        }
        *e=*s->top;
        s->top--;
}

int StackLen(sqStack *s)
{
        return (s->top-s->bottom);
}

void Cleanup(sqStack *s)   
{
        int LEN=s->stackSize;
        int i;
        for(i=0;i<LEN;i++)
        {
                free(s->bottom);
                s->bottom++;
        }
        s->bottom=s->top=NULL;
        s->stackSize=0;       
}
一个通过栈实现的逆波兰计算器,调试过程跳出这个弹窗,请问是什么意思?{:10_291:}

小酒酒呢 发表于 2018-12-24 08:03:53

楼主您好 。 这种问题一般都是指针越界访问了系统区造成的。 楼主可以放一下问题代码段。一起分析一下。

Luker 发表于 2018-12-24 18:35:42

小酒酒呢 发表于 2018-12-24 08:03
楼主您好 。 这种问题一般都是指针越界访问了系统区造成的。 楼主可以放一下问题代码段。一起分析一下。

哥们,代码贴上去了,请你帮我看看,多谢{:10_254:}

小酒酒呢 发表于 2018-12-24 23:21:39

Luker 发表于 2018-12-24 18:35
哥们,代码贴上去了,请你帮我看看,多谢

不知楼主的问题急不急   我现在身边没有电脑可不可以明天帮您看看。

Luker 发表于 2018-12-24 23:43:07

小酒酒呢 发表于 2018-12-24 23:21
不知楼主的问题急不急   我现在身边没有电脑可不可以明天帮您看看。

不急,你肯帮我看已是万分感激,多谢{:10_287:}

Luker 发表于 2018-12-27 00:16:58

小酒酒呢 发表于 2018-12-24 23:21
不知楼主的问题急不急   我现在身边没有电脑可不可以明天帮您看看。

哥们,你不会是忘了吧{:5_96:}

小酒酒呢 发表于 2018-12-27 10:02:40

Luker 发表于 2018-12-27 00:16
哥们,你不会是忘了吧

不好意思不好意思我们最近突然做课程设计。有一丢丢忙,放心小哥哥,你先自己分析分析,我一定抽时间给你满意回复

人造人 发表于 2018-12-27 12:39:43

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define STACKINCREMENT 10   //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'

typedef char ElemType;
typedef struct                  //栈的结构体
{
        ElemType *bottom;         //栈底指针
        ElemType *top;                              //栈顶指针
        int stackSize;                              //栈的大小
}sqStack;

void InitStack(sqStack *s);          //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s, ElemType e);         //入栈
void Pop(sqStack *s, ElemType *e);         //出栈      
int StackLen(sqStack *s);                         //返回栈的当前容量
void Cleanup(sqStack *s);                         //清空栈      

int main(void)
{
        sqStack s;


        InitStack(&s);                // 这里






        ElemType end, c, e;
        int first, second;
        printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
        scanf("%c", &c);
        while(c != '\n')                              //判断输入是否为结束计算的标识
        {
                if(c == addition || c == division || c == subtraction || c == multiplication)   //当输入为这四个运算符中的其中一个时
                {
                        Pop(&s, &e);         //出栈并将其值赋给second
                        second = e - '0';
                        Pop(&s, &e);         //出栈并将其值赋给first
                        first = e - '0';
                        if(c == addition)   //加法运算
                        {
                                end = first + second + 48;
                        }
                        if(c == division)                //除法运算
                        {
                                end = first / second + 48;
                        }
                        if(c == subtraction)      //减法运算
                        {
                                end = first - second + 48;
                        }
                        if(c == multiplication)      //乘法运算
                        {
                                end = first * second + 48;
                        }
                        Push(&s, end);                        //将运算的结果压入栈中
                }
                else
                {
                        Push(&s, c);                              //压栈
                }
                scanf("%c", &c);                           //获取下一个输入
        }
        Pop(&s, &e);                                                //出栈
        printf("计算结果:%d", e - '0');      //显示最后的结果
       
        // 这个函数存在逻辑问题,自己好好想一想为什么
        //Cleanup(&s);                                        //清空栈
        return 0;
}

void InitStack(sqStack *s)
{
        s->bottom = (ElemType *)malloc(STACKINCREMENT * sizeof(ElemType));
        if(!s->bottom)       //申请失败时
        {
                exit(0);
        }
        s->top = s->bottom;
        s->stackSize = STACKINCREMENT;
}

void Push(sqStack *s, ElemType e)
{
        if(s->top - s->bottom >= s->stackSize)          //若栈已满
        {
                s->bottom = (ElemType *)realloc(s->bottom, (s->stackSize + STACKINCREMENT) * sizeof(ElemType)); //增加栈的容量
                if(!s->bottom)                                  //申请失败时
                {
                        exit(0);
                }
        }
        *(++s->top) = e;
}

void Pop(sqStack *s, ElemType *e)
{
        if(s->top == s->bottom)                              //栈为空时
        {
                exit(0);
        }
        *e = *s->top;
        s->top--;
}

int StackLen(sqStack *s)
{
        return (s->top - s->bottom);
}

/* 这个函数不对
void Cleanup(sqStack *s)
{
        int LEN = s->stackSize;
        int i;
        for(i = 0; i<LEN; i++)
        {
                free(s->bottom);
                s->bottom++;
        }
        s->bottom = s->top = NULL;
        s->stackSize = 0;
}*/

小酒酒呢 发表于 2018-12-27 17:16:13

哇、、被楼上的小哥哥抢先了{:10_266:}。我还是要说一下,其实问题看似复杂,其实都出在粗心上。使用栈并没有初始化。全篇的出栈入栈,都没有对 stacksize 更新。楼上给你留了问题,那么我也就不点破了,免得浪费楼上苦心。楼主自己思考下吧,以后细心一些就好了,尤其在对于这些指针的处理上。

Luker 发表于 2018-12-27 21:27:34

人造人 发表于 2018-12-27 12:39


#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#define STACKINCREMENT 10   //栈的最大容量
#define addition '+'
#define division '/'
#define subtraction '-'
#define multiplication '*'

typedef char ElemType;
typedef struct                  //栈的结构体
{
        ElemType *bottom;         //栈底指针
        ElemType *top;                                //栈顶指针
        int stackSize;                                //栈的大小
}sqStack;

void InitStack(sqStack *s);          //创建一个最大容量为STASCKINCREMENT的栈
void Push(sqStack *s,ElemType e);       //入栈
void Pop(sqStack *s,ElemType *e);       //出栈       
int StackLen(sqStack *s);                       //返回栈的当前容量
void Cleanup(sqStack *s);                       //清空栈       

int main(void)
{
        sqStack s;       
        InitStack(&s);               
        ElemType end,c,e;
        int first,second;
        printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
        scanf("%c",&c);                               
        while(c!='\n')                                //判断输入是否为结束计算的标识
        {
                if(c==addition || c==division || c==subtraction ||c==multiplication)   //当输入为这四个运算符中的其中一个时
                {
                        Pop(&s,&e);         //出栈并将其值赋给second
                        second=e-'0';               
                        Pop(&s,&e);         //出栈并将其值赋给first
                        first=e-'0';
                        if(c==addition)   //加法运算
                        {
                                end=first+second+48;
                        }
                        if(c==division)                //除法运算
                        {
                                end=first/second+48;
                        }
                        if(c==subtraction)        //减法运算
                        {
                                end=first-second+48;
                        }
                        if(c==multiplication)        //乘法运算
                        {
                                end=first*second+48;
                        }
                        Push(&s,end);                        //将运算的结果压入栈中
                }
                else
                {
                        Push(&s,c);                                //压栈
                }
                scanf("%c",&c);                           //获取下一个输入
        }
        Pop(&s,&e);                                                //出栈
        printf("计算结果:%d",e-'0');        //显示最后的结果
        Cleanup(&s);                                        //清空栈
        return 0;       
}

void InitStack(sqStack *s)
{
        s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
        if(!s->bottom)       //申请失败时
        {
                exit(0);
        }
        s->top=s->bottom;
        s->stackSize=STACKINCREMENT;
}

void Push(sqStack *s,ElemType e)
{
        if(s->top-s->bottom>=s->stackSize)          //若栈已满
        {
                s->bottom=(ElemType *)realloc(s->bottom,(s->stackSize+STACKINCREMENT)*sizeof(ElemType)); //增加栈的容量
                if(!s->bottom)                                //申请失败时
                {
                        exit(0);
                }
        }
        *(++s->top)=e;
}

void Pop(sqStack *s,ElemType *e)
{
        if(s->top==s->bottom)                                //栈为空时
        {
                exit(0);
        }
        *e=*s->top;
        s->top--;
}

int StackLen(sqStack *s)
{
        return (s->top-s->bottom);
}

void Cleanup(sqStack *s)   
{
        int LEN=StackLen(s);
        ElemType *temp,*head;
        head=s->bottom;
        s->bottom++;
        int i;
        for(i=0;i<LEN;i++)
        {       
                temp=s->bottom;
                s->bottom++;       
                free(temp);
        }
        head=s->top=NULL;
        s->stackSize=0;       
}
DL,你看现在可以了吗?对于你的帮助万分感激

Luker 发表于 2018-12-27 21:31:15

小酒酒呢 发表于 2018-12-27 17:16
哇、、被楼上的小哥哥抢先了。我还是要说一下,其实问题看似复杂,其实都出在粗心上。使用栈并没 ...

多谢哥们,我老是要犯这种低级的错误,唉,还是练得不够,我这里的stacksize是整个栈的最大容量,一般不变,我里面已经用stackLen函数来获取这个栈的当前容量了,不知道这样理解对不对,还望赐教{:5_108:}

小酒酒呢 发表于 2018-12-27 22:05:52

Luker 发表于 2018-12-27 21:31
多谢哥们,我老是要犯这种低级的错误,唉,还是练得不够,我这里的stacksize是整个栈的最大容量,一般不 ...

从严蔚敏教材角度看,stacksize应该是当前栈中使用的元素,初始化为0。而设一个最大栈的容量,这个为固定不变的。然后就是建议楼主找找malloc和free函数的关系,看看free的释放是释放那些空间,以免之后还会出现问题。还是学习造人大佬,给大家留思考余地{:10_334:}

人造人 发表于 2018-12-27 23:04:37

Luker 发表于 2018-12-27 21:27
#include
#include
#include


不可以
Clean和Destroy是不一样的
一个malloc对应一个free,且只能对应一个

void InitStack(sqStack *s)
{
      s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
      if(!s->bottom)       //申请失败时
      {
                exit(0);
      }
      s->top=s->bottom;
      s->stackSize=STACKINCREMENT;
}


void Cleanup(sqStack *s)   
{
      int LEN=StackLen(s);
      ElemType *temp,*head;
      head=s->bottom;
      s->bottom++;
      int i;
      for(i=0;i<LEN;i++)
      {      
                temp=s->bottom;
                s->bottom++;      
                free(temp);
      }
      head=s->top=NULL;
      s->stackSize=0;      
}

人造人 发表于 2018-12-27 23:06:18

malloc了一次
free了LEN次

Luker 发表于 2018-12-27 23:16:51

小甲鱼的数据结构与算法里是这么讲的{:10_262:}

Luker 发表于 2018-12-27 23:17:47

人造人 发表于 2018-12-27 23:06
malloc了一次
free了LEN次

被小甲鱼的数据结构与算法的教程坑了{:5_96:}

人造人 发表于 2018-12-27 23:21:40

Luker 发表于 2018-12-27 23:17
被小甲鱼的数据结构与算法的教程坑了

贴一下视频链接

Luker 发表于 2018-12-27 23:58:15

人造人 发表于 2018-12-27 23:21
贴一下视频链接

https://www.bilibili.com/video/av29175690/?p=2
在栈的那几节就有提到栈的清除,他就是这么讲的

人造人 发表于 2018-12-28 01:10:26

@小甲鱼
我好像记得很久之前我就已经提过这个问题了
页: [1]
查看完整版本: 一个调试过程中的错误,请各位热心鱼油看一下