当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 13 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-04 21:17 
头像

注册: 2009-08-14 16:24
帖子: 314
送出感谢: 0 次
接收感谢: 0 次
鼓捣着写一个读取任意长度的字符串的东西。。。~~


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

代码:
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
图表1.jpg [ 44.98 KiB | 被浏览 617 次 ]



_________________
我很乖的。。。
页首
 用户资料  
 
2 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-04 21:26 
头像

注册: 2008-12-13 19:39
帖子: 13284
地址: 物华天宝人杰地灵
送出感谢: 1
接收感谢: 6
召唤大蛇。。。 :em04


_________________
行到水穷处,坐看云起时。
海内生明月,天涯共此夕。
--------------------吾本独!


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 8:56 
头像

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


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 9:37 
头像

注册: 2009-08-14 16:24
帖子: 314
送出感谢: 0 次
接收感谢: 0 次
:em05 :em05


_________________
我很乖的。。。


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 9:47 
头像

注册: 2008-02-12 19:47
帖子: 262
送出感谢: 0 次
接收感谢: 0 次
关于realloc和strcat那块说错了。如果前面的内存正确分配并复制了,它两者的配合是没问题的。
第一次那块要么用calloc和strcat的组合,要么用malloc和strcpy的组合。malloc和strcat的组合肯定是有问题的。


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 9:50 
头像

注册: 2006-05-03 0:39
帖子: 8273
地址: المريخ
送出感谢: 0 次
接收感谢: 1
:em20 流程图。。。。。


_________________
PHP是最好的语言!不服来战!


页首
 用户资料  
 
7 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 11:53 

注册: 2009-02-24 19:39
帖子: 159
送出感谢: 0 次
接收感谢: 0 次
实在是太乱了,strcat 是通过找 '\0' 来确定字符串的末端的,malloc 又不会清内存,根本无法达到目的。第一个程序指针都没有做初始化就直接对它 realloc……两个程序传给 realloc 的地址弄成它的返回地址,典型的内存泄漏隐患……估计问题还多,自己慢慢看吧。


页首
 用户资料  
 
8 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 12:16 
头像

注册: 2006-05-03 0:39
帖子: 8273
地址: المريخ
送出感谢: 0 次
接收感谢: 1
anewbie 写道:
指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。


_________________
PHP是最好的语言!不服来战!


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 13:11 
头像

注册: 2009-05-05 20:45
帖子: 568
送出感谢: 0 次
接收感谢: 0 次
流程图。。。
多少年没碰这个了。


_________________
The world never lacks miracles.


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 13:21 
头像

注册: 2008-02-12 19:47
帖子: 262
送出感谢: 0 次
接收感谢: 0 次
stlxv 写道:
anewbie 写道:
指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。

不,是错的。此处p是定义在局部的,所以未初始化值是不确定的。而realloc要求传递给它的指针要么是经过malloc,calloc或realloc这类函数在堆上分配的内存地址的指针,要么是NULL空指针。其中后一种情况符合你说,但此处指针并不是空的,此处指针内容是未定义的,程序运行到那会出错。

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

PS:楼主此帖帖了两段程序,其中第一段实际上帖错了。第一段那个if(i == 3)实际上应该是if(i == 1),也就是说下面那段才是正确的。要不根本不能正常运行。


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-05 16:00 

注册: 2009-02-24 19:39
帖子: 159
送出感谢: 0 次
接收感谢: 0 次
stlxv 写道:
anewbie 写道:
指针都没有做初始化就直接对它 realloc…
这是对的,相当于malloc。
P.S. 俺没看贴。

扯,那指针又不是 NULL.


页首
 用户资料  
 
12 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-06 0:09 
头像

注册: 2009-08-14 16:24
帖子: 314
送出感谢: 0 次
接收感谢: 0 次
抓狂,一整天都上不到这论坛(那两个笑脸不知是怎么发的,难道被盗号?),终于手机上了,但还是看的很不爽,明天继续。谢谢大家。


_________________
我很乖的。。。


页首
 用户资料  
 
13 楼 
 文章标题 : Re: 菜鸟的程序又出错了,有流程图帮助高手解答,谢谢。。
帖子发表于 : 2010-03-11 23:04 

注册: 2010-02-28 9:11
帖子: 38
送出感谢: 0 次
接收感谢: 0 次
结果要求是不是这样:
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;
}


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 13 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译