一、静态检测的方法
下载个cppcheck 软件,该方法就是将整个工程代码加载,然后判断的。只检测编译器无法发现的bug,检测malloc和free 是否匹配。
二、使用 mtrace 进行检测
在该方法当中,需要在代码中添加头文件 #include <mcheck.h> ,然后添加对应的函数setenv("MALLOC_TRACE", "output.log", 1); 以及 mtrace();
请看示例代码
#include <stdio.h>
#include <mcheck.h>
int main()
{
setenv("MALLOC_TRACE","output.log",1); //output.log
mtrace();
char *p = (char *)malloc(10);
if(p == NULL)
{
perror("malloc error\n");
}
printf("Test Malloc successfully \n");
muntrace(); //这一行看情况添加,相当与是和前面的配对,形成一个调试的范围
return 0;
}
然后进行编译
# gcc Test.c -o Test
#./mtraceTest 这步执行完后,可在当前目录看到 output.log 文件
#mtrace Test output.log
可以看到以下 内容,说明有内存没有释放
#Memory not freed:
-----------------
Address Size Caller
0x0000556b389888e0 0xa at 0x556b36c8b1fc
#
#
#
#
#
但是这个只能看到是否有内存泄漏,我还不知道如何定位是在哪个函数里
三、使用 Valgrind 进行检测
这个就详细一些。首先查看在环境是否已经配置 algrind 命令,如果没有,就先安装。我是在Ubuntu环境下进行调试的,所有没有搭建交叉编译的valgrind 环境,直接一行命令搞定。
#sudo apt-get install valgrind
该命令还可以调试多线程执行文件
请看示例代码
先看没有包含多线程代码的
#include <stdio.h>
#include <string.h>
#include <error.h>
int main()
{
char *p = (char *)malloc(8);
char *pp = (char *)malloc(8);
if(p == NULL)
{
perror("Malloc error \n");
return 0;
}
printf("Test Malloc successfully \n");
//free(p);
return 0;
}
然后执行以下命令进行编译,执行
#gcc Test.c -o run
#valgrind --leak-check=full --trace-children=yes --undef-value-errors=no --track-fds=yes --num-callers=50 --log-file=valgrind_log ./run -d
# ls 在当前目录下就可以看到 valgrind_log
# cat valgrind_log 就可以看到详细的内容,valgrind这个命令还可以定位到是在那个函数里申请了内存
valgrind这个命令还可以定位到是在那个函数里申请了内存
带有多线程的程序也一样可以调试
请看示例代码
#include <stdio.h>
#include <string.h>
#include <error.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int *Lam()
{
int *x = NULL;
x = (int *) malloc(sizeof(int)*10);
return x;
}
void *Pthread_1(void)
{
int a = 0;
while(1)
{
printf("pthread %d\n",a);
int *x = Lam();
sleep(2);
a++;
if(a > 3)
{
pthread_exit(0);
}
}
}
int main()
{
char *p = (char *)malloc(8);
char *pp = (char *)malloc(8);
if(p == NULL)
{
perror("Malloc error \n");
return 0;
}
printf("Malloc successfully \n");
//free(p);
pthread_t P1;
pthread_create(&P1,NULL , (void *)Pthread_1,NULL);
pthread_join(P1,NULL);
return 0;
}
然后执行编译调试命令
#gcc Test.c -o run -lpthread
#valgrind --leak-check=full --trace-children=yes --undef-value-errors=no --track-fds=yes --num-callers=50 --log-file=valgrind_log ./run -d
# ls 在当前目录下就可以看到 valgrind_log
# cat valgrind_log 就可以看到详细的内容,valgrind这个命令还可以定位到是在那个函数里申请了内存