鱼C论坛

 找回密码
 立即注册
查看: 1211|回复: 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
#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;
}*/
屏幕截图(362).png
屏幕截图(358).png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

哥们,代码贴上去了,请你帮我看看,多谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

不知楼主的问题急不急   我现在身边没有电脑  可不可以明天帮您看看。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

不急,你肯帮我看已是万分感激,多谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

哥们,你不会是忘了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

不好意思不好意思  我们最近突然做课程设计。有一丢丢忙,放心小哥哥,你先自己分析分析,我一定抽时间给你满意回复
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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;
}*/
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

评分

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

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> 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,你看现在可以了吗?对于你的帮助万分感激
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

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

使用道具 举报

发表于 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;        
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-27 23:06:18 | 显示全部楼层
malloc了一次
free了LEN次
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-27 23:16:51 | 显示全部楼层
小甲鱼的数据结构与算法里是这么讲的
屏幕截图(336).png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

被小甲鱼的数据结构与算法的教程坑了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

贴一下视频链接
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

https://www.bilibili.com/video/av29175690/?p=2
在栈的那几节就有提到栈的清除,他就是这么讲的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-28 01:10:26 | 显示全部楼层
@小甲鱼
我好像记得很久之前我就已经提过这个问题了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-3 02:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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