linux下编程遇到的一个疑难杂症——野指针所带来的害处

本文介绍了一个单进程多线程程序中出现的双释堆内存问题。该问题在程序正常运行时未被发现,在主进程销毁时引发错误。通过代码审查发现,一个已分配的指针在未置为NULL的情况下被二次释放,导致了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景:

    一段代码,单进程多线程模式,除了main线程还有很多个子线程,里面大量地使用了指针,代码编译没有任何的warning和error;程序跑起来后一切正常,并和另外一个程序通过socket 网络通信,也一切正常;所有的子线程退出也正常;所有类的析构函数析构的时候也正常。但是:就在main进程销毁(或者通过exit(0))退出的时候,操作系统就

提示以下错误:

*** glibc detected *** ./fsvspsiu: corrupted double-linked list: 0x08484100 ***
======= Backtrace: =========
/lib/libc.so.6[0x3bce1b]
/lib/libc.so.6[0x3be7fb]
/lib/libc.so.6(cfree+0x90)[0x3c20f0]
./fsvspsiu[0x804d4c5]
./fsvspsiu[0x804c411]
./fsvspsiu[0x804a134]
/lib/libc.so.6(exit+0xee)[0x38163e]
/lib/libc.so.6(__libc_start_main+0xe8)[0x36b398]
./fsvspsiu(__gxx_personality_v0+0x69)[0x8049211]
======= Memory map: ========
00110000-00111000 r-xp 00110000 00:00 0          [vdso]
00336000-00351000 r-xp 00000000 fd:00 332652     /lib/ld-2.7.so
00351000-00352000 r-xp 0001a000 fd:00 332652     /lib/ld-2.7.so
00352000-00353000 rwxp 0001b000 fd:00 332652     /lib/ld-2.7.so
00355000-004a8000 r-xp 00000000 fd:00 332653     /lib/libc-2.7.so
004a8000-004aa000 r-xp 00153000 fd:00 332653     /lib/libc-2.7.so
004aa000-004ab000 rwxp 00155000 fd:00 332653     /lib/libc-2.7.so
004ab000-004ae000 rwxp 004ab000 00:00 0
004b0000-004d7000 r-xp 00000000 fd:00 332657     /lib/libm-2.7.so
004d7000-004d8000 r-xp 00026000 fd:00 332657     /lib/libm-2.7.so
004d8000-004d9000 rwxp 00027000 fd:00 332657     /lib/libm-2.7.so
004e2000-004f7000 r-xp 00000000 fd:00 332655     /lib/libpthread-2.7.so
004f7000-004f8000 r-xp 00014000 fd:00 332655     /lib/libpthread-2.7.so
004f8000-004f9000 rwxp 00015000 fd:00 332655     /lib/libpthread-2.7.so
004f9000-004fb000 rwxp 004f9000 00:00 0
00cab000-00cb6000 r-xp 00000000 fd:00 332676     /lib/libgcc_s-4.1.2-20070925.so.1
00cb6000-00cb7000 rwxp 0000a000 fd:00 332676     /lib/libgcc_s-4.1.2-20070925.so.1
03694000-03774000 r-xp 00000000 fd:00 415472     /usr/lib/libstdc++.so.6.0.8
03774000-03778000 r-xp 000df000 fd:00 415472     /usr/lib/libstdc++.so.6.0.8
03778000-03779000 rwxp 000e3000 fd:00 415472     /usr/lib/libstdc++.so.6.0.8
03779000-0377f000 rwxp 03779000 00:00 0
08048000-08052000 r-xp 00000000 00:14 85112      /mnt/hgfs/d/fsvsp/src/pf/siu/fsvspsiu
08052000-08053000 rw-p 00009000 00:14 85112      /mnt/hgfs/d/fsvsp/src/pf/siu/fsvspsiu
08053000-08057000 rw-p 08053000 00:00 0
08452000-08486000 rw-p 08452000 00:00 0
b5600000-b5621000 rw-p b5600000 00:00 0
b5621000-b5700000 ---p b5621000 00:00 0
b5718000-b5719000 ---p b5718000 00:00 0
b5719000-b6119000 rw-p b5719000 00:00 0
b6119000-b611a000 ---p b6119000 00:00 0
b611a000-b6b1a000 rw-p b611a000 00:00 0
b6b1a000-b6b1b000 ---p b6b1a000 00:00 0
b6b1b000-b751b000 rw-p b6b1b000 00:00 0
b751b000-b751c000 ---p b751b000 00:00 0
b751c000-b7f1f000 rw-p b751c000 00:00 0
bfe86000-bfe9b000 rw-p bffea000 00:00 0          [stack]
Aborted

 

     1. 通过一翻周折,终于找到了问题的根源:

看上面操作系统提示信息的第五行( /lib/libc.so.6(cfree+0x90)[0x3c20f0] ),可以估计应该是堆内存被free的时候出了问题,那么free()函数最有可能会出现问题的情况是什么呢

——堆被多次释放了。

     2. 通过代码审核,发现:

有个malloc 出来的指针,不小心被free了,但是没有被赋值成NULL,变成野指针,下次使用的时候该野指针(已经被free)不等于NULL,所以使用该指针,使用完后又free了一次,造成了free两次的情况。

    3. 还没有弄懂的问题:

操作系统为什么不在第二次free的时候报错,而是在整个进程退出的时候报错,太不厚道了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值