gdb调试时出现glibc detected *** free(): invalid pointer: 0x000000000060101c

当程序在堆上动态分配内存并忘记或多次释放时,可能会遇到glibc检测到的`free(): invalid pointer`错误。本文探讨了如何通过gdb调试此类问题,以及内存泄漏和重复释放内存的危害。强调了动态内存管理的重要性,即正确地申请和释放内存以避免未定义行为和内存泄漏。

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

程序的内存空间分为全局变量区,栈空间,堆空间等多部分,通常栈空间都不大,几M的大小,开一个长度为几十万的整型数组,栈空间就受不了,要告诉你stackflow了。
使用malloc函数动态申请堆空间内存会是一个好的解决方案,但要时刻牢记配套的free对动态内存进行释放

#edfine ARRAYLENGTH 100000
int *ia = (int*) malloc(sizeof(int)*ARRAYLENGTH);
free(ia);
ia = NULL;

在堆上申请二维数组的内存空间,也比较简单

int (*ia2)[4] = (int (*) [4])malloc(sizeof(int)*4*ARRAYLENGTH);
for(int i=0;i<4;++i)
{
	free(ia2[i];
	ia2[i] = NULL;
}

按照我的理解,ia2是指针的数组,那肯定需要挨个进行释放,才能保证正确释放动态内存,但事实上这一段程序出现了一个问题。在用gdb进行调试时,出现了*** glibc detected *** /home/EngzSinger/test: free(): invalid pointer: 0x000000000060101c ***的错误,从这里我们可以得知,程序中我们使用了已经被释放的指针作为参数调用free

[EngzSinger@master]$ gdb ./test
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/EngzSinger/test...done.
(gdb) l
1	#include <stdlib.h>
2	#include <stdio.h>
3	
4	int main()
5	{
6		int (*ia)[3] = (int(*)[3])malloc(sizeof(int)*3*9);
7		int (*ia1)[3];
8		for(int i=0;i<3;++i)
9		{
10			free(ia[i]);
(gdb) l
11			ia[i]=NULL;
12		}
13		return 0;
14	}
(gdb) b 12
Breakpoint 1 at 0x40054c: file free_test.c, line 12.
(gdb) r
Starting program: /home/EngzSinger/test 
*** glibc detected *** /home/EngzSinger/test: free(): invalid pointer: 0x000000000060101c ***
======= Backtrace: =========
/lib64/libc.so.6[0x341b675dee]
/lib64/libc.so.6[0x341b678c3d]
/home/EngzSinger/test[0x400542]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x341b61ed1d]
/home/EngzSinger/test[0x400449]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:11 26918960                           /home/EngzSinger/test
00600000-00601000 rw-p 00000000 08:11 26918960                           /home/EngzSinger/test
00601000-00622000 rw-p 00000000 00:00 0                                  [heap]
341b200000-341b220000 r-xp 00000000 08:03 124518487                      /lib64/ld-2.12.so
341b420000-341b421000 r--p 00020000 08:03 124518487                      /lib64/ld-2.12.so
341b421000-341b422000 rw-p 00021000 08:03 124518487                      /lib64/ld-2.12.so
341b422000-341b423000 rw-p 00000000 00:00 0 
341b600000-341b78a000 r-xp 00000000 08:03 124518610                      /lib64/libc-2.12.so
341b78a000-341b98a000 ---p 0018a000 08:03 124518610                      /lib64/libc-2.12.so
341b98a000-341b98e000 r--p 0018a000 08:03 124518610                      /lib64/libc-2.12.so
341b98e000-341b990000 rw-p 0018e000 08:03 124518610                      /lib64/libc-2.12.so
341b990000-341b994000 rw-p 00000000 00:00 0 
341fa00000-341fa16000 r-xp 00000000 08:03 124518975                      /lib64/libgcc_s-4.4.7-20120601.so.1
341fa16000-341fc15000 ---p 00016000 08:03 124518975                      /lib64/libgcc_s-4.4.7-20120601.so.1
341fc15000-341fc16000 rw-p 00015000 08:03 124518975                      /lib64/libgcc_s-4.4.7-20120601.so.1
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0 
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0 
7ffff7fd9000-7ffff7fdc000 rw-p 00000000 00:00 0 
7ffff7ffc000-7ffff7ffe000 rw-p 00000000 00:00 0 
7ffff7ffe000-7ffff7fff000 r-xp 00000000 00:00 0                          [vdso]
7ffffffe9000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Program received signal SIGABRT, Aborted.
0x000000341b632495 in raise () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.209.el6_9.2.x86_64 libgcc-4.4.7-18.el6.x86_64

进一步的使用valgrind对程序进行内存监控,能发现total heap usage: 1 allocs, 9 frees, 108 bytes allocated,对动态内存进行了一次分配,进行了3次释放,由此造成了错误。

[EngzSinger@master]$ valgrind ./test
==22495== Memcheck, a memory error detector
==22495== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==22495== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==22495== Command: ./test
==22495== 
==22495== Invalid free() / delete / delete[] / realloc()
==22495==    at 0x4A06430: free (vg_replace_malloc.c:446)
==22495==    by 0x400541: main (free_test.c:10)
==22495==  Address 0x4c3104c is 12 bytes inside a block of size 108 free'd
==22495==    at 0x4A06430: free (vg_replace_malloc.c:446)
==22495==    by 0x400541: main (free_test.c:10)
==22495== 
==22495== 
==22495== HEAP SUMMARY:
==22495==     in use at exit: 0 bytes in 0 blocks
==22495==   total heap usage: 1 allocs, 3 frees, 108 bytes allocated
==22495== 
==22495== All heap blocks were freed -- no leaks are possible
==22495== 
==22495== For counts of detected and suppressed errors, rerun with: -v
==22495== ERROR SUMMARY: 8 errors from 1 contexts (suppressed: 8 from 6)

造成这个错误的原因就是重复释放了动态内存,在使用动态内存的时候一定要牢记: malloc申请的动态内存一定要有配套的free进行正确释放

  • 如果忘记释放,会造成内存泄漏
  • 如果释放后仍使用指针访问相应的内存,则会造成未定义的行为
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值