如何检测C语言中的内存漏洞(leak)?

在动态分配的内存单元(即由函数malloc()或ealloc()分配的内存单元)不再使用却没有被释放的情况下,会出现内存漏洞。未释放内存单元本身并不是一种错误,编译程序不会因此报告出错,程序也不会因此而立即崩溃。但是,如果不再使用而又没有被释放的内存单元越来越多,程序所能使用的内存空间就越来越小。最终,当程序试图要求分配内存时,就会发现已经没有可用的内存空间。这时,尤其是当程序员没有考虑到内存分配失败的可能性时,程序的运行就会出现异常现象。

内存漏洞是最难检测的错误之一,同时也是最危险的错误。导致这个问题的编程错误很可能出现在程序的开始部分,但只有当程序奠名其妙地使用完内存后,这个问题才会暴露出来。

此时去检查当前那条导致内存分配失败的语句是无济于事的,因为那些分配了内存却未能按时释放内存的代码可能在程序的其它地方。

遗憾的是C语言并没有为检测或修复内存漏洞提供现成的方法。除非使用提供这种功能的商业软件包,否则,程序员就需要以很大的耐心和精力去检测和修复内存漏洞。最好的办法是在编写程序时就充分考虑到内存漏洞的可能性,并小心谨慎地处理这种可能性。

导致内存漏洞的最简单的也是最常见的原因是忘记释放分配给临时缓冲区的内存空间,请看下述程序段:
# include <stdio. h>
# include <stdlib. h>
/*
* Say hello to the user's and put the user's name in UPPERCASE.
*/
void SayHi( char *name )
{
char * UpName;
int a;
UpName = malloc( strlen( name ) +1);
/ * Allocate space for the name * /
for( a =0; a<strlen( name ); ++a)
UpName[a] = toupper( name[a]) ;
UpName [a] = '\0'i
printf("Hello, %si\n", UpName );
}
int main()
{
SayHi( "Dave" );
return( 0 );
}
这段程序中的问题是显而易见的——它为存储使用大写字母的名字分配了临时空间,但从未释放这些空间。为了保证永远不发生类似的情况,你可以采用这样的方法:在分配内存的每条语句后加上相应的free语句,然后把使用这些临时内存的语句插到这两条语句之间。只要在程序中分配和释放内存的语句之间没有break,continue或goto语句,这种方法就能保证每次分配的空间在使用完后就被释放掉。

上述方法相当繁琐,并且不能完全避免内存漏洞的出现,因为在实际编程中,所分配的内存空间的使用时间往往是不能预测的。此外,如果操作或删除内存空间的程序段有错误,也会出现内存漏洞。例如,在删除链表的过程中,最后一个结点可能会丢失,或者一个指向内存空间的指针可能会被改写。解决这类问题的办法只能是小心谨慎地编写程序,或者象前面提到的那样使用相应的软件包,或者利用语言的扩展功能。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当涉及到内存泄漏时,我们需要使用一些工具来检测和解决这个问题。其一个常用的工具是 Valgrind,它可以检测内存泄漏和其它内存错误。以下是一个简单的 C 语言程序,使用 Valgrind检测内存泄漏: ``` #include <stdlib.h> int main() { int *ptr = malloc(sizeof(int)); *ptr = 42; free(ptr); return 0; } ``` 在终端运行以下命令: ``` valgrind --leak-check=full ./a.out ``` Valgrind 将会输出内存泄漏的详细信息,如果没有内存泄漏,它将会输出类似于以下的信息: ``` ==12345== HEAP SUMMARY: ==12345== in use at exit: 0 bytes in 0 blocks ==12345== total heap usage: 1 allocs, 1 frees, 4 bytes allocated ==12345== ==12345== All heap blocks were freed -- no leaks are possible ==12345== ==12345== For counts of detected and suppressed errors, rerun with: -v ==12345== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` 如果有内存泄漏,它将会输出类似于以下的信息: ``` ==12345== HEAP SUMMARY: ==12345== in use at exit: 4 bytes in 1 blocks ==12345== total heap usage: 2 allocs, 1 frees, 8 bytes allocated ==12345== ==12345== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==12345== by 0x4005B7: main (in /path/to/program) ==12345== ==12345== LEAK SUMMARY: ==12345== definitely lost: 4 bytes in 1 blocks ==12345== indirectly lost: 0 bytes in 0 blocks ==12345== possibly lost: 0 bytes in 0 blocks ==12345== still reachable: 0 bytes in 0 blocks ==12345== suppressed: 0 bytes in 0 blocks ==12345== ==12345== For counts of detected and suppressed errors, rerun with: -v ==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ``` 这个程序没有内存泄漏,所以 Valgrind 输出了 "no leaks are possible" 的信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值