程序的内存空间分为全局变量区,栈空间,堆空间等多部分,通常栈空间都不大,几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
进行正确释放
- 如果忘记释放,会造成内存泄漏
- 如果释放后仍使用指针访问相应的内存,则会造成未定义的行为