陈越姥姥的数据结构试验指导案例2-3疑问

destiny9613 2018-09-15 07:50:54
#include<stdio.h>
#include<string.h>

#define MAXN 30
#define MAXSTRING 64

int count;
void search(int remainder, int start, char *sTerms);

main() {
char sTerms[MAXSTRING]="";
int n;

scanf_s("%d", &n);
sprintf_s(sTerms, 3,"%d=", n);
search(n, 1, sTerms);
if (count % 4 != 0)
printf("\n");
}

void search(int remainder, int start, char *sTerms) {
char sTmp[MAXSTRING];
strcpy_s(sTmp, MAXSTRING, sTerms);
for (int i = start; i <= remainder; i++) {
if (remainder - i >= i) {
printf("%d\n", strlen(sTerms));
sprintf_s(sTmp + strlen(sTerms), MAXSTRING, "%d+", i);
search(remainder - i, i, sTmp);
}
else {
printf("%d\n", strlen(sTerms));
sprintf_s(sTmp + strlen(sTerms), MAXSTRING, "%d", i);
count++;
if (count % 4 != 1)
printf(";");
printf("%s", sTmp);
if (count % 4 == 0)
printf("\n");
return;
}
}
}

运行完打印出一个式子后出现错误如下图:

网上说是数组越限,但不知道为什么会越限
...全文
271 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-09-17
  • 打赏
  • 举报
回复
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
b[(a=rand()%11)]=0;
Sleep(100);
b[(a=rand()%11)]=1;
Sleep(100);
b[(a=rand()%11)]=2;
Sleep(100);
b[(a=rand()%11)]=3;
Sleep(100);
b[(a=rand()%11)]=4;
Sleep(100);
}
return 0;
}
赵4老师 2018-09-17
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
zangfong 2018-09-16
  • 打赏
  • 举报
回复
不怎么用VS编程,对*_s系列函数不熟,于是我改为原版的scanf, sprintf,运行正常(我指的是没有出错,不过结果估计不是你想要的),代码如下
#include<stdio.h>
#include<string.h>

#define MAXN 30
#define MAXSTRING 64

int count;
void search(int remainder, int start, char *sTerms);

main() {
char sTerms[MAXSTRING]="";
int n;

scanf("%d", &n);
sprintf(sTerms, "%d=", n);
search(n, 1, sTerms);
if (count % 4 != 0)
printf("\n");
}

void search(int remainder, int start, char *sTerms) {
char sTmp[MAXSTRING];
strcpy(sTmp, sTerms);
for (int i = start; i <= remainder; i++) {
if (remainder - i >= i) {
printf("%d\n", strlen(sTerms));
sprintf(sTmp + strlen(sTerms), "%d+", i);
search(remainder - i, i, sTmp);
}
else {
printf("%d\n", strlen(sTerms));
sprintf(sTmp + strlen(sTerms), "%d", i);
count++;
if (count % 4 != 1)
printf(";");
printf("%s", sTmp);
if (count % 4 == 0)
printf("\n");
return;
}
}
}

所以我估计问题出在微软的应该是sprintf_s这个函数。在debug时,问题是出现在search函数返回时,我估计是跟你的sprintf_s写法有关,参考一下以下几个百度百科的例子
j = sprintf_s( buffer, 200, " String: %s\n", s );
j += sprintf_s( buffer + j, 200 - j, " Character: %c\n", c );
j += sprintf_s( buffer + j, 200 - j, " Integer: %d\n", i );
j += sprintf_s( buffer + j, 200 - j, " Real: %f\n", fp );

你就会猜到
sprintf_s(sTmp + strlen(sTerms), MAXSTRING, "%d", i);

这种拷贝的方法,使得sTmp[MAXSTRING]总共长度为MAXSTRING(64)的字符数组,在拷贝的过程中长度变成了MAXSTRING+strlen(sTerms),肯定越界,不知道是不是search函数调用结束,临时变量sTmp[MAXSTRING]在销毁时,系统发现其越界,所以报错?总之,我的意思是,你把
sprintf_s(sTmp + strlen(sTerms), MAXSTRING, "%d+", i);
对应的都修改为
sprintf_s(sTmp + strlen(sTerms), MAXSTRING-strlen(sTerms), "%d+", i);
保持sTmp 的总长度为MAXSTRING,则程序就能正常运行了。


faihung 2018-09-16
  • 打赏
  • 举报
回复
其实算起来程序本身没有问题,数据溢出,算是外在因素导致的。上面说的
zangfong 2018-09-16
  • 打赏
  • 举报
回复
不过MAXSTRING定义了64确实是有点小,如果我输入的值超过30,例如,31就又挂了。

另外
	sprintf_s(sTerms, 3, "%d=", n);
这里3也小了,只能输入10以内的数(因为算上'\0',刚好3位),所以如果输入的数字超过10,这里也要相应调整,如果是两位数的话,这里就至少应该是4,三位数则至少应该是5,以此类推。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧