鱼C论坛

 找回密码
 立即注册
查看: 1501|回复: 18

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

[复制链接]
发表于 2018-12-23 17:13:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 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;       
}
一个通过栈实现的逆波兰计算器,调试过程跳出这个弹窗,请问是什么意思?
最佳答案
2018-12-27 12:39:43
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>

  4. #define STACKINCREMENT 10     //栈的最大容量
  5. #define addition '+'
  6. #define division '/'
  7. #define subtraction '-'
  8. #define multiplication '*'

  9. typedef char ElemType;
  10. typedef struct                  //栈的结构体
  11. {
  12.         ElemType *bottom;           //栈底指针
  13.         ElemType *top;                                //栈顶指针
  14.         int stackSize;                                //栈的大小
  15. }sqStack;

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

  21. int main(void)
  22. {
  23.         sqStack s;


  24.         InitStack(&s);                // 这里






  25.         ElemType end, c, e;
  26.         int first, second;
  27.         printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
  28.         scanf("%c", &c);
  29.         while(c != '\n')                                //判断输入是否为结束计算的标识
  30.         {
  31.                 if(c == addition || c == division || c == subtraction || c == multiplication)   //当输入为这四个运算符中的其中一个时
  32.                 {
  33.                         Pop(&s, &e);         //出栈并将其值赋给second
  34.                         second = e - '0';
  35.                         Pop(&s, &e);         //出栈并将其值赋给first
  36.                         first = e - '0';
  37.                         if(c == addition)     //加法运算
  38.                         {
  39.                                 end = first + second + 48;
  40.                         }
  41.                         if(c == division)                //除法运算
  42.                         {
  43.                                 end = first / second + 48;
  44.                         }
  45.                         if(c == subtraction)        //减法运算
  46.                         {
  47.                                 end = first - second + 48;
  48.                         }
  49.                         if(c == multiplication)        //乘法运算
  50.                         {
  51.                                 end = first * second + 48;
  52.                         }
  53.                         Push(&s, end);                        //将运算的结果压入栈中
  54.                 }
  55.                 else
  56.                 {
  57.                         Push(&s, c);                                //压栈
  58.                 }
  59.                 scanf("%c", &c);                           //获取下一个输入
  60.         }
  61.         Pop(&s, &e);                                                //出栈
  62.         printf("计算结果:%d", e - '0');        //显示最后的结果
  63.        
  64.         // 这个函数存在逻辑问题,自己好好想一想为什么
  65.         //Cleanup(&s);                                        //清空栈
  66.         return 0;
  67. }

  68. void InitStack(sqStack *s)
  69. {
  70.         s->bottom = (ElemType *)malloc(STACKINCREMENT * sizeof(ElemType));
  71.         if(!s->bottom)       //申请失败时
  72.         {
  73.                 exit(0);
  74.         }
  75.         s->top = s->bottom;
  76.         s->stackSize = STACKINCREMENT;
  77. }

  78. void Push(sqStack *s, ElemType e)
  79. {
  80.         if(s->top - s->bottom >= s->stackSize)          //若栈已满
  81.         {
  82.                 s->bottom = (ElemType *)realloc(s->bottom, (s->stackSize + STACKINCREMENT) * sizeof(ElemType)); //增加栈的容量
  83.                 if(!s->bottom)                                  //申请失败时
  84.                 {
  85.                         exit(0);
  86.                 }
  87.         }
  88.         *(++s->top) = e;
  89. }

  90. void Pop(sqStack *s, ElemType *e)
  91. {
  92.         if(s->top == s->bottom)                                //栈为空时
  93.         {
  94.                 exit(0);
  95.         }
  96.         *e = *s->top;
  97.         s->top--;
  98. }

  99. int StackLen(sqStack *s)
  100. {
  101.         return (s->top - s->bottom);
  102. }

  103. /* 这个函数不对
  104. void Cleanup(sqStack *s)
  105. {
  106.         int LEN = s->stackSize;
  107.         int i;
  108.         for(i = 0; i<LEN; i++)
  109.         {
  110.                 free(s->bottom);
  111.                 s->bottom++;
  112.         }
  113.         s->bottom = s->top = NULL;
  114.         s->stackSize = 0;
  115. }*/
复制代码
屏幕截图(362).png
屏幕截图(358).png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-12-24 08:03:53 | 显示全部楼层
楼主您好 。 这种问题一般都是指针越界访问了系统区造成的。 楼主可以放一下问题代码段。一起分析一下。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

哥们,代码贴上去了,请你帮我看看,多谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-24 23:21:39 From FishC Mobile | 显示全部楼层
Luker 发表于 2018-12-24 18:35
哥们,代码贴上去了,请你帮我看看,多谢

不知楼主的问题急不急   我现在身边没有电脑  可不可以明天帮您看看。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

不急,你肯帮我看已是万分感激,多谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 00:16:58 | 显示全部楼层
小酒酒呢 发表于 2018-12-24 23:21
不知楼主的问题急不急   我现在身边没有电脑  可不可以明天帮您看看。

哥们,你不会是忘了吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 10:02:40 From FishC Mobile | 显示全部楼层
Luker 发表于 2018-12-27 00:16
哥们,你不会是忘了吧

不好意思不好意思  我们最近突然做课程设计。有一丢丢忙,放心小哥哥,你先自己分析分析,我一定抽时间给你满意回复
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 12:39:43 | 显示全部楼层    本楼为最佳答案   
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>

  4. #define STACKINCREMENT 10     //栈的最大容量
  5. #define addition '+'
  6. #define division '/'
  7. #define subtraction '-'
  8. #define multiplication '*'

  9. typedef char ElemType;
  10. typedef struct                  //栈的结构体
  11. {
  12.         ElemType *bottom;           //栈底指针
  13.         ElemType *top;                                //栈顶指针
  14.         int stackSize;                                //栈的大小
  15. }sqStack;

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

  21. int main(void)
  22. {
  23.         sqStack s;


  24.         InitStack(&s);                // 这里






  25.         ElemType end, c, e;
  26.         int first, second;
  27.         printf("请以后缀表达式的形式输入你要进行的计算(以回车键作为运算结束的标识).\n");
  28.         scanf("%c", &c);
  29.         while(c != '\n')                                //判断输入是否为结束计算的标识
  30.         {
  31.                 if(c == addition || c == division || c == subtraction || c == multiplication)   //当输入为这四个运算符中的其中一个时
  32.                 {
  33.                         Pop(&s, &e);         //出栈并将其值赋给second
  34.                         second = e - '0';
  35.                         Pop(&s, &e);         //出栈并将其值赋给first
  36.                         first = e - '0';
  37.                         if(c == addition)     //加法运算
  38.                         {
  39.                                 end = first + second + 48;
  40.                         }
  41.                         if(c == division)                //除法运算
  42.                         {
  43.                                 end = first / second + 48;
  44.                         }
  45.                         if(c == subtraction)        //减法运算
  46.                         {
  47.                                 end = first - second + 48;
  48.                         }
  49.                         if(c == multiplication)        //乘法运算
  50.                         {
  51.                                 end = first * second + 48;
  52.                         }
  53.                         Push(&s, end);                        //将运算的结果压入栈中
  54.                 }
  55.                 else
  56.                 {
  57.                         Push(&s, c);                                //压栈
  58.                 }
  59.                 scanf("%c", &c);                           //获取下一个输入
  60.         }
  61.         Pop(&s, &e);                                                //出栈
  62.         printf("计算结果:%d", e - '0');        //显示最后的结果
  63.        
  64.         // 这个函数存在逻辑问题,自己好好想一想为什么
  65.         //Cleanup(&s);                                        //清空栈
  66.         return 0;
  67. }

  68. void InitStack(sqStack *s)
  69. {
  70.         s->bottom = (ElemType *)malloc(STACKINCREMENT * sizeof(ElemType));
  71.         if(!s->bottom)       //申请失败时
  72.         {
  73.                 exit(0);
  74.         }
  75.         s->top = s->bottom;
  76.         s->stackSize = STACKINCREMENT;
  77. }

  78. void Push(sqStack *s, ElemType e)
  79. {
  80.         if(s->top - s->bottom >= s->stackSize)          //若栈已满
  81.         {
  82.                 s->bottom = (ElemType *)realloc(s->bottom, (s->stackSize + STACKINCREMENT) * sizeof(ElemType)); //增加栈的容量
  83.                 if(!s->bottom)                                  //申请失败时
  84.                 {
  85.                         exit(0);
  86.                 }
  87.         }
  88.         *(++s->top) = e;
  89. }

  90. void Pop(sqStack *s, ElemType *e)
  91. {
  92.         if(s->top == s->bottom)                                //栈为空时
  93.         {
  94.                 exit(0);
  95.         }
  96.         *e = *s->top;
  97.         s->top--;
  98. }

  99. int StackLen(sqStack *s)
  100. {
  101.         return (s->top - s->bottom);
  102. }

  103. /* 这个函数不对
  104. void Cleanup(sqStack *s)
  105. {
  106.         int LEN = s->stackSize;
  107.         int i;
  108.         for(i = 0; i<LEN; i++)
  109.         {
  110.                 free(s->bottom);
  111.                 s->bottom++;
  112.         }
  113.         s->bottom = s->top = NULL;
  114.         s->stackSize = 0;
  115. }*/
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
人造人 + 5 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 21:27: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;       
        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,你看现在可以了吗?对于你的帮助万分感激
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

多谢哥们,我老是要犯这种低级的错误,唉,还是练得不够,我这里的stacksize是整个栈的最大容量,一般不变,我里面已经用stackLen函数来获取这个栈的当前容量了,不知道这样理解对不对,还望赐教
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

从严蔚敏教材角度看,stacksize应该是当前栈中使用的元素,初始化为0。而设一个最大栈的容量,这个为固定不变的。然后就是建议楼主找找malloc和free函数的关系,看看free的释放是释放那些空间,以免之后还会出现问题。还是学习造人大佬,给大家留思考余地
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 23:04:37 | 显示全部楼层
Luker 发表于 2018-12-27 21:27
#include
#include
#include

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

  1. void InitStack(sqStack *s)
  2. {
  3.         s->bottom=(ElemType *)malloc(STACKINCREMENT*sizeof(ElemType));
  4.         if(!s->bottom)       //申请失败时
  5.         {
  6.                 exit(0);
  7.         }
  8.         s->top=s->bottom;
  9.         s->stackSize=STACKINCREMENT;
  10. }
复制代码

  1. void Cleanup(sqStack *s)     
  2. {
  3.         int LEN=StackLen(s);
  4.         ElemType *temp,*head;
  5.         head=s->bottom;
  6.         s->bottom++;
  7.         int i;
  8.         for(i=0;i<LEN;i++)
  9.         {        
  10.                 temp=s->bottom;
  11.                 s->bottom++;        
  12.                 free(temp);
  13.         }
  14.         head=s->top=NULL;
  15.         s->stackSize=0;        
  16. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 23:06:18 | 显示全部楼层
malloc了一次
free了LEN次
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 23:16:51 | 显示全部楼层
小甲鱼的数据结构与算法里是这么讲的
屏幕截图(336).png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 23:17:47 | 显示全部楼层
人造人 发表于 2018-12-27 23:06
malloc了一次
free了LEN次

被小甲鱼的数据结构与算法的教程坑了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 23:21:40 | 显示全部楼层
Luker 发表于 2018-12-27 23:17
被小甲鱼的数据结构与算法的教程坑了

贴一下视频链接
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 23:58:15 | 显示全部楼层

https://www.bilibili.com/video/av29175690/?p=2
在栈的那几节就有提到栈的清除,他就是这么讲的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-28 01:10:26 | 显示全部楼层
@小甲鱼
我好像记得很久之前我就已经提过这个问题了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-12 14:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表