这个大数求模程序在VC中单步调试正常,但是运行起来会内存错,搞不懂
下面这个程序运行起来会出错,导致程序死,但是我单步调试却可以一步一步得到结果,并顺利结束退出,这是为什么呢?
还有一个问题就是,大家可以自己改一下main函数里的参与计算的数值,它有时候是可以算出结果,有时候就会出错,我很无解,还求各路C++高手看看。
相应的函数有注释:
C/C++ code
#include <iostream> #include <math.h> #include <string.h> #include <time.h> using namespace std; char* sub(char *numa,char *numb); char *findend(char *num); int compare(char *numa,char*numb); char *mod(char *numa,char *numb); void reverse(char *s); char *clearzero(char *num); char *mod(char *numa,char *numb) //求模函数 { int slong = strlen(numa), sshort = strlen(numb), contin,i = 0; int cp = compare(numa,numb); char *result = NULL,*temp = NULL,*mid = NULL,*latter =NULL; if(cp == 0) return numa; else if(cp == 2) { result = "0"; return result; } else { if(slong - sshort <= 2) //如果两个数相差位数不多,就可以用减法来算余数 { temp = numa; sshort = strlen(numb); while(contin) { temp = sub(temp,numb); cp = compare(temp,numb); if(cp == 1) contin = 1; else if(cp == 2) { contin = 0; result = "0"; } else { contin = 0; result = temp; } } } else //如果相差太大,减法算会耗费很长时间,就用改进的方法计算 { mid = new char[sshort+1+1]; latter = new char[slong-sshort]; mid[sshort+1] = '\0'; latter[slong-sshort-1] = '\0'; for(i=0;i<sshort+1;i++) { mid[i] = numa[i]; } for(i=0;i<slong-sshort-1;i++) { latter[i] = numa[sshort+1+i]; } temp = strcat(mod(mid,numb),latter); clearzero(temp); delete mid; delete latter; result = mod(temp,numb); } return result; } } char *clearzero(char *num) //清除无效的“0”,比如把“0091”处理成“91” { int length = strlen(num); int i = length - 1; reverse(num); while(num[i] == 48) { num[i] = '\0'; i--; } reverse(num); return num; } void reverse(char *s) //颠倒字符串的顺序,因为有的函数是逆序储存字符串结果的,而求在clearzero函数中也要用。 { int i,j; char t; for(i=0,j=strlen(s)-1;i<j;i++,j--) t=s[i],s[i]=s[j],s[j]=t; } char* sub(char *numa,char *numb)//大数相减函数,现在目前没有实现处理负数出现的代码,因为在这个例子中不会出现小数减大数的情况 { char *temp; int carry = 0,loop; int slong,sshort; char *pl = NULL,*ps = NULL; if(compare(numa,numb) > 0) { pl = findend(numa); ps = findend(numb); slong = strlen(numa); sshort = strlen(numb); loop = strlen(numa); } else { pl = findend(numb); ps = findend(numa); slong = strlen(numb); sshort = strlen(numa); } temp = new char[slong+1]; temp[loop]='\0'; while(loop > 0) { if(loop > slong - sshort) { if(*pl > *ps) { temp[loop-1] = *pl - *ps + 48 - carry; carry = 0; } else if(*pl == *ps) { if(carry == 1) { temp[loop-1] = *pl + 10 -*ps - carry + 48; carry = 1; } else { temp[loop-1]= 48; carry = 0; } } else { temp[loop-1] = *pl + 10 -*ps - carry + 48; carry = 1; } } else { if(*pl == 48 && carry ==1) { temp[loop-1] = 57; carry = 1; } else { temp[loop-1] = *pl - carry; carry = 0; } } pl--;ps--; loop--; } return clearzero(temp); } char *findend(char *num) //用来返回num字符串的最后一个字符的位置 { num += strlen(num)-1; return num; } int compare(char *numa,char*numb) //比较numa和numb的大小,如果numa>numb返回1,numa=numb返回2,numa<numb返回0 { int slong = strlen(numa); int sshort = strlen(numb); char *pna = numa; char *pnb = numb; if (slong > sshort) return 1; if (slong == sshort) { while (*pna) { if(*pna > *pnb) return 1; else if(*pna < *pnb) return 0; else if(*pna == *pnb) { pna++; pnb++; } } return 2; } return 0; } int main () //主函数 { char *a = "45321432432144321432154"; char *b = "21322"; char *result = a; result = mod(a,b); cout<<result<<endl; return 0; }
作者: lovejoyy 发布时间: 2011-06-13
作者: nfer_cn 发布时间: 2011-06-13
作者: lovejoyy 发布时间: 2011-06-13
C/C++ code
char *a = "45321432432132154"; char *b = "21322";
就可以算出结果11918
作者: lovejoyy 发布时间: 2011-06-13
比如取:
C/C++ code
char *a = "45321432432132154";
char *b = "21322";
就可以算出结果11918
确实DebugOK,但是运行却出错!
作者: nfer_cn 发布时间: 2011-06-13
引用 3 楼 lovejoyy 的回复:
比如取:
C/C++ code
char *a = "45321432432132154";
char *b = "21322";
就可以算出结果11918
确实DebugOK,但是运行却出错!
哎,困扰了我两天了,还是不能解决。。心都碎了
作者: lovejoyy 发布时间: 2011-06-13
引用 4 楼 nfer_cn 的回复:
引用 3 楼 lovejoyy 的回复:
比如取:
C/C++ code
char *a = "45321432432132154";
char *b = "21322";
就可以算出结果11918
确实DebugOK,但是运行却出错!
哎,困扰了我两天了,还是不能解决。。心都碎了
问题定位了,在sub函数中126行,第22次调用new时出现问题,不过还没想出解决办法!
作者: nfer_cn 发布时间: 2011-06-13
else //如果相差太大,减法算会耗费很长时间,就用改进的方法计算 { mid = new char[sshort+1+1]; latter = new char[slong-sshort]; char * temp2 = new char[slong]; memset(temp2, 0x0, slong); mid[sshort+1] = '\0'; latter[slong-sshort-1] = '\0'; for(i=0;i<sshort+1;i++) { mid[i] = numa[i]; } for(i=0;i<slong-sshort-1;i++) { latter[i] = numa[sshort+1+i]; } //temp = strcat(mod(mid,numb),latter); temp = mod(mid, numb); memcpy(temp2,temp,strlen(temp)); strcat(temp2,latter); clearzero(temp2); delete mid; delete latter; result = mod(temp2,numb); delete temp2; }
OK了,替换下你的54行的else,OK了
问题出在内存泄露上
作者: nfer_cn 发布时间: 2011-06-13
引用 5 楼 lovejoyy 的回复:
引用 4 楼 nfer_cn 的回复:
引用 3 楼 lovejoyy 的回复:
比如取:
C/C++ code
char *a = "45321432432132154";
char *b = "21322";
就可以算出结果11918
确实DebugOK,但是运行却出错!
哎,困扰了我两天了,还是……
对,我也发现了,那个temp字符串变成了“”,照理说应该不会是空的吧?或者是不是申请了要先memset一下?
作者: lovejoyy 发布时间: 2011-06-13
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
作者: nfer_cn 发布时间: 2011-06-13
你原来的特姆坡一直是个野指针!
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
诶?麻烦说详细点么,还没想通 呵呵
作者: lovejoyy 发布时间: 2011-06-13
大数的四则运算及求模
作者: pathuang68 发布时间: 2011-06-13
引用 9 楼 nfer_cn 的回复:
你原来的特姆坡一直是个野指针!
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
诶?麻烦说详细点么,还没想通 呵呵
说实话,我也不是很清楚,不过感觉你应该清楚的一下几个地方:
1.strcat(mod(mid,numb),latter) mod(mid,numb)返回的指针指向的内存在哪里开辟的?
2.strcat函数中第一个指针是否能保存下两个字符串连接的长度
3.result = mod(temp,numb)同理,result指向的内存是谁管理的?请明确!
建议把mod函数重写下,其他的函数模块化还是很好的
作者: nfer_cn 发布时间: 2011-06-13
引用 10 楼 lovejoyy 的回复:
引用 9 楼 nfer_cn 的回复:
你原来的特姆坡一直是个野指针!
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
诶?麻烦说详细点么,还没想通 呵呵
说实话,我也不是很清楚,不过感觉你应该清楚的一下几个地方:
1.strcat(mod(mid,nu……
恩,多谢指点!我取完善一下mod函数~
作者: lovejoyy 发布时间: 2011-06-13
引用 12 楼 nfer_cn 的回复:
引用 10 楼 lovejoyy 的回复:
引用 9 楼 nfer_cn 的回复:
你原来的特姆坡一直是个野指针!
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
诶?麻烦说详细点么,还没想通 呵呵
说实话,我也不是很清楚,不过感觉你应该清楚的一下几个……
互相进步!
个人一点意见:
1、学会使用项目管理工具,如:GIT,SVN之类的
2、一定要养成良好的编程规范
3、多学习开源代码
作者: nfer_cn 发布时间: 2011-06-13
引用 13 楼 lovejoyy 的回复:
引用 12 楼 nfer_cn 的回复:
引用 10 楼 lovejoyy 的回复:
引用 9 楼 nfer_cn 的回复:
你原来的特姆坡一直是个野指针!
temp = strcat(mod(mid,numb),latter);
这一行的问题,我刚开始就觉得就不对劲!
诶?麻烦说详细点么,还没想通 呵呵
说……
呵呵 多谢前辈如此耐心!在VC下面的确不太熟练,以后要抓紧!
作者: lovejoyy 发布时间: 2011-06-13