BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #85055同步于 2015/1/7
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

问一个关于malloc函数和fgets的问题

yu1336199790
2015/1/7镜像同步5 回复
#include<stdio.h> #include<stdlib.h> #define SIZE 20//max.rows #define MAXSTEPS (SIZE*SIZE)//max.steps struct point{short r;short c;}; char **maze; struct point *path,*bestpath; int rows,cols,sp=MAXSTEPS;//rows/cols that user inputs,shortestPath int x[4]={0,1,0,-1},y[4]={-1,0,1,0};//Left,Down,Right,Up //check if the position is reasonable int LegalPos(int r,int c) { if ((r<0)||(c<0)||(r>rows-1)||(c>cols-1)) return 0; return 1; } //visit the maze from the point(r,c) at step. void Visit(int step,int r,int c) { int d,i;//direction int newr,newc;//newrow,newcol for (d=0;d<4;d++){//four directions to move newr=r+x[d]; newc=c+y[d]; if (LegalPos(newr,newc)&&('#'!=*(*(maze+newr)+newc))){//check if we can move to (newr,newc) path[step].r=newr;//record the point in path. path[step].c=newc; if ('E'==*(*(maze+newr)+newc)){//check if we reach the end if (step<sp){//if find shorter path sp=step; for (i=0;i<=step;i++){//copy the path to bestpath bestpath[i].r=path[i].r; bestpath[i].c=path[i].c; } } } if ('.'==*(*(maze+newr)+newc)){//if we can pass the point *(*(maze+newr)+newc)='V';//mark the point as Visited Visit(step+1,newr,newc);//continue visit the maze *(*(maze+newr)+newc)='.';//backtrace:remark it path[step].r=SIZE;//reset the path at step path[step].c=SIZE; } } } } int main() { int r,c,found=0,i; printf("Please input the row and column of the maze(<=20):"); scanf("%d %d",&rows,&cols); if ((rows<0)||(cols<0)||(rows>SIZE-1)||(cols>SIZE-1)){ printf("error input\n"); return -1; } maze=(char **)malloc(sizeof(char *)*rows); if (!maze){ printf("error while malloc maze\n"); return -1; } for(i=0;i<rows;i++){ maze[i]=(char*)malloc(sizeof(char)*(cols)); if (!maze[i]){ printf("error while malloc maze\n"); return -1; } } path=(struct point *)malloc(sizeof(struct point)*rows*cols); if (!path){ printf("error while malloc path\n"); return -1; } bestpath=(struct point *)malloc(sizeof(struct point)*rows*cols); if (!bestpath){ printf("error while malloc bestpath\n"); return -1; } printf("Please input the strings:\n"); fflush(stdin); for(r=0;r<rows;r++) { fgets(*(maze+r),cols+2,stdin); } //find out the point which we start from for(r=0;r<rows;r++){ for(c=0;c<cols;c++){ if('S'==*(*(maze+r)+c)){ found=1;break; } } if (found) break; } //record it in path path[0].r=r;path[0].c=c; //visit the maze from START point. Visit(1,r,c); //print the bestpath info. for(i=0;i<=sp;i++) printf("(%d,%d)\n",bestpath[i].r+1,bestpath[i].c+1); system("pause"); return 0; } 该程序是上课老师给我们讲的找迷宫程序,楼主是大一,希望学长学姐帮忙解决一下! 上面两处蓝色的地方,我非常一会malloc申请空间的时候(char *)以rows个空间,因为fgets函数用时必须多读入两个字符\n \0但是空间只有那么点 多读入的去哪了?没存吗? 当我把fgets函数中+2去掉后 这个程序就不行了 显示的很奇怪的看不懂 这是为什么呢 多读入的没存 为何又起了该起的作用呢
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
yu1336199790机器人#1 · 2015/1/7
该程序是上课老师给我们讲的找迷宫程序,楼主是大一,希望学长学姐帮忙解决一下! 上面两处蓝色的地方,我非常不懂 malloc申请空间的时候(char *)乘rows 个空间,因为fgets函数用时必须多读入两个字符\n \0但是空间只有那么点 多读入的去哪了?没存吗? 当我把fgets函数中+2去掉后 这个程序就不行了 显示的很奇怪的看不懂 这是为什么呢 多读入的没存 为何又起了该起的作用呢
FromSixToTen机器人#2 · 2015/1/7
字太大啦,吓死爷啦。标记渗入吧。
FromSixToTen机器人#3 · 2015/1/7
关键在这两个地方:maze=(char **)malloc(sizeof(char *)*rows); maze[i]=(char*)malloc(sizeof(char)*(cols)); 指针的指针分配空间,类似理解为二维数组。另外不知道你说的什么,就晃眼啦。
succubus机器人#4 · 2015/1/9
不要搞大字报啊 你应该标的是maze[i]=(char*)malloc(sizeof(char)*(cols));和 fgets(*(maze+r),cols+2,stdin); 在你老老实实输入col个字符的情况下,这里fgets读入了cols+1个字符,其中前col个字符是你输入的字符,第col+1个是换行符,第col+2个是fgets函数自动加上的'\0' 假设col是4,那么你为*(maze+r)也就是maze[i]申请的内存就是Addr,Addr+1,Addr+2,Addr+3。 而你通过fgets函数读的字符串就放到Addr,Addr+1,Addr+2,Addr+3,Addr+4,Addr+5的内存上了 明白了吗?也就是内存越界访问了,专业点儿的说法就是缓冲区溢出了。 你可以试验一下把maze[i]=(char*)malloc(sizeof(char)*(cols));改成maze[i]=(char*)malloc(sizeof(char)); 这程序看上去也能正常运行,但它是有安全隐患的
yu1336199790机器人#5 · 2015/1/9
【 在 succubus 的大作中提到: 】 : 不要搞大字报啊 : 你应该标的是maze[i]=(char*)malloc(sizeof(char)*(cols));和 fgets(*(maze+r),cols+2,stdin); : 在你老老实实输入col个字符的情况下,这里fgets读入了cols+1个字符,其中前col个字符是你输入的字符,第col+1个是换行符,第col+2个是fgets函数自动加上的'\0' : ................... 就是说读入的最后是被存到了不知道的区域 ?