dt3tc 发表于 2015-5-30 13:07:40

C语言

本帖最后由 dt3tc 于 2015-6-1 10:31 编辑

谢谢
bash-4.3$ make
gcc 1.c -Wall -g -o 1
bash-4.3$ ./1
a
pbuffer=
*** Error in `./1': free(): invalid pointer: 0x08b6f00a ***
======= Backtrace: =========
/lib/libc.so.6(+0x6b716)
/lib/libc.so.6(+0x7414a)
/lib/libc.so.6(cfree+0x50)
./1
/lib/libc.so.6(__libc_start_main+0xf7)
./1
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:03 805443458/home/mxf/Dev/myself/C/1/1
08049000-0804a000 r--p 00000000 08:03 805443458/home/mxf/Dev/myself/C/1/1
0804a000-0804b000 rw-p 00001000 08:03 805443458/home/mxf/Dev/myself/C/1/1
08b6f000-08b90000 rw-p 00000000 00:00 0         
b7524000-b7525000 rw-p 00000000 00:00 0
b7525000-b76ec000 r-xp 00000000 fd:00 265595   /usr/lib/libc-2.21.so
b76ec000-b76ee000 r--p 001c7000 fd:00 265595   /usr/lib/libc-2.21.so
b76ee000-b76ef000 rw-p 001c9000 fd:00 265595   /usr/lib/libc-2.21.so
b76ef000-b76f2000 rw-p 00000000 00:00 0
b76f6000-b7712000 r-xp 00000000 fd:00 268576   /usr/lib/libgcc_s-5.1.1-20150422.so.1
b7712000-b7713000 r--p 0001b000 fd:00 268576   /usr/lib/libgcc_s-5.1.1-20150422.so.1
b7713000-b7714000 rw-p 0001c000 fd:00 268576   /usr/lib/libgcc_s-5.1.1-20150422.so.1
b7714000-b7718000 rw-p 00000000 00:00 0
b7718000-b771a000 r--p 00000000 00:00 0         
b771a000-b771b000 r-xp 00000000 00:00 0         
b771b000-b773d000 r-xp 00000000 fd:00 272604   /usr/lib/ld-2.21.so
b773d000-b773e000 r--p 00021000 fd:00 272604   /usr/lib/ld-2.21.so
b773e000-b773f000 rw-p 00022000 fd:00 272604   /usr/lib/ld-2.21.so
bfb79000-bfb9a000 rw-p 00000000 00:00 0         
已放弃 (核心已转储)
bash-4.3$ cat 1.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
    char *pbuffer;
    pbuffer=(char *)calloc(20,sizeof(char));
    if(pbuffer!=NULL)
    {
      while((*pbuffer++=getchar())!='\n')
      {
            printf("pbuffer=%c\n",*pbuffer);
      }
    }
    free(pbuffer);
    return 0;
}
bash-4.3$


ryxcaixia 发表于 2015-5-30 13:07:41


搜索
复制
楼主注意!
1. 你输入的是a和回车, 而回车默认的字符就是\n(再严格来说应该是\r\n)
所以在第一次循环的时候, 缓冲区里的字符已经是'a'和'\n'换句话说
第二次的循环直接就跳出了




2. 其实跳出就跳出循环吧, 无非就是20个缓冲区里就一个字符, 释放空间也没啥
但是! 楼主 有一种东西叫做局部释放, 对的! pbuffer本来是你申请内存的首地址
但是每次循环你竟然让这个首地址自增.
可以看到此时的pbuffer 是空, 即已经自动指向了下一个位置.
而前一个位置(pbuffer - 1)就是那个回车字符'\n'
再前一个位置(pbuffer - 2)的字符串就是'a\n'
所以楼主, 你对内存进行了"局部释放", 即free的并不是当初申请的这块堆内存的首地址, 而是其中的局部地址这和野指针是一样的危害, 内存自然叮咚的一声报错了
ps: 建议申请了地址后, 首地址buff就不要动了
要么利用下表操作符即buff, buff这种
要么再顶一个迭代器如char* iter = buff; 然后利用iter去迭代赋值

buxiaode 发表于 2015-5-30 19:28:03

看看,学习学习

桃花飞舞 发表于 2015-5-30 20:04:23

:call:

我是一只小菜鸟 发表于 2015-6-1 13:27:11

{:9_224:}

dt3tc 发表于 2015-6-2 11:31:32

我是一只小菜鸟 发表于 2015-6-1 13:27


我还是建议你发个真大腿更好
页: [1]
查看完整版本: C语言