菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

软件和网站开发以及相关技术探讨
回复
头像
小锐同学
帖子: 314
注册时间: 2009-08-14 16:24

菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#1

帖子 小锐同学 » 2010-03-04 21:17

鼓捣着写一个读取任意长度的字符串的东西。。。~~


理想很丰满,现实很骨感。。

代码: 全选

lucifer@DearBaby:~/CC$ cat ReadAll1.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
    char buf[3];
    int  i = 1;
    int count = 3;
    char *p;

    while(count == 3)
	{
        count = read(STDIN_FILENO, buf, 3);
        if(count == 3)
    	{
            if(i == 3)
    		{
                p = (char *)malloc(sizeof(char) * 3);
        		i++;
                strcat(p, buf);
                continue;
    		}
        	else
    		{
                p = realloc(p, sizeof(char) * 3 * i++);
                strcat(p, buf);
                continue;
    		}
    	}
        else
    	{
            if(i == 1)
                printf("%s", buf);
        	else
                printf("%s", p);
    	}
    }
}
lucifer@DearBaby:~/CC$ cc ReadAll1.c 
lucifer@DearBaby:~/CC$ ./a.out
wehflqoiejufljsdv;sd

oie0�juf0�ljs0�dv;0�sd
0�lucifer@DearBaby:~/CC$
这上面怎么要按两次回车才输出?而且输出的还有乱码?

之后我用define来使那个3更换为MY_LINE,却输出了一堆东西,而且还不能读取“;”了。这又为什么?

代码: 全选

lucifer@DearBaby:~/CC$ cat ReadAll.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define MY_LINE 3
int
main(void)
{
    char buf[MY_LINE];
    int  i = 1;
    int count = MY_LINE;
    char *p;

    while(count == MY_LINE)
	{
        count = read(STDIN_FILENO, buf, MY_LINE);
        if(count == MY_LINE)
    	{
            if(i == 1)
    		{
                p = (char *)malloc(sizeof(char) * MY_LINE);
        		i++;
                strcat(p, buf);
                continue;
    		}
        	else
    		{
                p = realloc(p, sizeof(char) * MY_LINE * i++);
                strcat(p, buf);
                continue;
    		}
    	}
        else
    	{
            if(i == 1)
                printf("%s", buf);
        	else
                printf("%s", p);
    	}
    }
}
lucifer@DearBaby:~/CC$ cc ReadAll.c
lucifer@DearBaby:~/CC$ ./a.out
wehflqoiejufljsdv;sd
*** glibc detected *** ./a.out: realloc(): invalid next size: 0x0000000001821010 ***
======= Backtrace: =========
/lib/libc.so.6[0x7f2a073e8dd6]
/lib/libc.so.6[0x7f2a073ee294]
/lib/libc.so.6(realloc+0xf0)[0x7f2a073ee5f0]
./a.out[0x4006de]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f2a07391abd]
./a.out[0x400599]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 675                                /home/lucifer/CC/a.out
00600000-00601000 r--p 00000000 08:03 675                                /home/lucifer/CC/a.out
00601000-00602000 rw-p 00001000 08:03 675                                /home/lucifer/CC/a.out
01821000-01842000 rw-p 00000000 00:00 0                                  [heap]
7f2a00000000-7f2a00021000 rw-p 00000000 00:00 0 
7f2a00021000-7f2a04000000 ---p 00000000 00:00 0 
7f2a0715c000-7f2a07172000 r-xp 00000000 08:08 9222                       /lib/libgcc_s.so.1
7f2a07172000-7f2a07371000 ---p 00016000 08:08 9222                       /lib/libgcc_s.so.1
7f2a07371000-7f2a07372000 r--p 00015000 08:08 9222                       /lib/libgcc_s.so.1
7f2a07372000-7f2a07373000 rw-p 00016000 08:08 9222                       /lib/libgcc_s.so.1
7f2a07373000-7f2a074d9000 r-xp 00000000 08:08 4436                       /lib/libc-2.10.1.so
7f2a074d9000-7f2a076d8000 ---p 00166000 08:08 4436                       /lib/libc-2.10.1.so
7f2a076d8000-7f2a076dc000 r--p 00165000 08:08 4436                       /lib/libc-2.10.1.so
7f2a076dc000-7f2a076dd000 rw-p 00169000 08:08 4436                       /lib/libc-2.10.1.so
7f2a076dd000-7f2a076e2000 rw-p 00000000 00:00 0 
7f2a076e2000-7f2a07701000 r-xp 00000000 08:08 4092                       /lib/ld-2.10.1.so
7f2a078da000-7f2a078dc000 rw-p 00000000 00:00 0 
7f2a078fd000-7f2a07900000 rw-p 00000000 00:00 0 
7f2a07900000-7f2a07901000 r--p 0001e000 08:08 4092                       /lib/ld-2.10.1.so
7f2a07901000-7f2a07902000 rw-p 0001f000 08:08 4092                       /lib/ld-2.10.1.so
7fffe6650000-7fffe6665000 rw-p 00000000 00:00 0                          [stack]
7fffe66c5000-7fffe66c6000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
忽略
lucifer@DearBaby:~/CC$ sd
sd: command not found
lucifer@DearBaby:~/CC$ 
这里又只要一次回车就可以了。
附件
图表1.jpg
我很乖的。。。
头像
wangdu2002
帖子: 13284
注册时间: 2008-12-13 19:39
来自: 物华天宝人杰地灵

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#2

帖子 wangdu2002 » 2010-03-04 21:26

召唤大蛇。。。 :em04
行到水穷处,坐看云起时。
海内生明月,天涯共此夕。
--------------------吾本独!
头像
liwangli
帖子: 262
注册时间: 2008-02-12 19:47

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#3

帖子 liwangli » 2010-03-05 8:56

问题出在malloc和realloc及strcat的配合上。第一次分配内存用了malloc,而malloc分配堆上的内存是不初始化的,即内容是不定的。而strcat要找到该段内存的第一个为空的位置来把第二个参数里的内容续上。所以如果内存是未初始化的,可能该段内存中全是有内容的,将导致越界复制。所以此处应该用calloc,calloc会将得到的内存清零。
但即使用calloc,后面的realloc和strcat配合依然有问题。realloc分配一段新的内存(也可能直接扩展,但同样不把新加内容初始化),并把原内存的内容copy过去,但是它并不把证复制过去内容后边的空间(就是多出来的空间)清零,所以就碰到了和前面一样的问题。
头像
小锐同学
帖子: 314
注册时间: 2009-08-14 16:24

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#4

帖子 小锐同学 » 2010-03-05 9:37

:em05 :em05
我很乖的。。。
头像
liwangli
帖子: 262
注册时间: 2008-02-12 19:47

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#5

帖子 liwangli » 2010-03-05 9:47

关于realloc和strcat那块说错了。如果前面的内存正确分配并复制了,它两者的配合是没问题的。
第一次那块要么用calloc和strcat的组合,要么用malloc和strcpy的组合。malloc和strcat的组合肯定是有问题的。
头像
stlxv
论坛版主
帖子: 8275
注册时间: 2006-05-03 0:39
来自: المريخ

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#6

帖子 stlxv » 2010-03-05 9:50

:em20 流程图。。。。。
PHP是最好的语言!不服来战!
anewbie
帖子: 159
注册时间: 2009-02-24 19:39

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#7

帖子 anewbie » 2010-03-05 11:53

实在是太乱了,strcat 是通过找 '\0' 来确定字符串的末端的,malloc 又不会清内存,根本无法达到目的。第一个程序指针都没有做初始化就直接对它 realloc……两个程序传给 realloc 的地址弄成它的返回地址,典型的内存泄漏隐患……估计问题还多,自己慢慢看吧。
头像
stlxv
论坛版主
帖子: 8275
注册时间: 2006-05-03 0:39
来自: المريخ

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#8

帖子 stlxv » 2010-03-05 12:16

anewbie 写了:指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。
PHP是最好的语言!不服来战!
头像
Destine
论坛版主
帖子: 568
注册时间: 2009-05-05 20:45

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#9

帖子 Destine » 2010-03-05 13:11

流程图。。。
多少年没碰这个了。
The world never lacks miracles.
头像
liwangli
帖子: 262
注册时间: 2008-02-12 19:47

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#10

帖子 liwangli » 2010-03-05 13:21

stlxv 写了:
anewbie 写了:指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。
不,是错的。此处p是定义在局部的,所以未初始化值是不确定的。而realloc要求传递给它的指针要么是经过malloc,calloc或realloc这类函数在堆上分配的内存地址的指针,要么是NULL空指针。其中后一种情况符合你说,但此处指针并不是空的,此处指针内容是未定义的,程序运行到那会出错。

当p是全局定义的时候,默认被初始化为空指针,就可以直接传给realloc了。

PS:楼主此帖帖了两段程序,其中第一段实际上帖错了。第一段那个if(i == 3)实际上应该是if(i == 1),也就是说下面那段才是正确的。要不根本不能正常运行。
anewbie
帖子: 159
注册时间: 2009-02-24 19:39

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#11

帖子 anewbie » 2010-03-05 16:00

stlxv 写了:
anewbie 写了:指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。
扯,那指针又不是 NULL.
头像
小锐同学
帖子: 314
注册时间: 2009-08-14 16:24

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#12

帖子 小锐同学 » 2010-03-06 0:09

抓狂,一整天都上不到这论坛(那两个笑脸不知是怎么发的,难道被盗号?),终于手机上了,但还是看的很不爽,明天继续。谢谢大家。
我很乖的。。。
xwg
帖子: 38
注册时间: 2010-02-28 9:11

Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。

#13

帖子 xwg » 2010-03-11 23:04

结果要求是不是这样:
w@ubuntu:~$ gcc shiyan.c
w@ubuntu:~$ ./a.out
0123

******************************
0123
******************************
01234567

******************************
0123
01234567
******************************
0123456789

******************************
0123
01234567
0123456789
******************************
asdgdfhgjjhj

******************************
0123
01234567
0123456789
asdgdfhgjjhj
******************************

是的话shiyan.c是这样的:

代码: 全选

//shiyan.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	char buf[4];
	int  i = 1,count = 0,allcount = 0;
	char *p;

	while(1){
		count = read(STDIN_FILENO,buf,3);
		*(buf+count) = '\0';
		allcount = allcount + count;

		if(i == 1){
			p = (char *)malloc( sizeof(char)*(count+1) );
			i++;
			strcat(p,buf);
		}else{
			p = (char *)realloc( p,sizeof(char)*(allcount+1) );
			strcat(p,buf);
		}
		
		if( *(buf+count-1) == '\n' ){
		printf("\n******************************\n%s******************************\n",p);
		}
	}
	free(p);
	return 0;
}
回复