第一 valgrind初步学习并深入使用

开始写第一篇的时候就是想记录一下自己当时怎么用的,后来想想还是应该深入的了解一下,方便以后使用。

所以我在官网下了使用手册来看看,并且自己写程序一点一点的分析,故意出错,看会给什么相应的信息。

官网手册下载地址:http://valgrind.org/docs/download_docs.html


对了补充一下:每个信息前面都有一个数字,并且每次的都是一样的,这个是进程ID号

在补充一点:就是在使用valgrind的时候信息是输出到标准错误上的,也就是stderr,文件描述符一般就是2了,所以我们在屏幕上运行的时候,一般打印到屏幕上是很乱的,所以输出到文件中比较容易查阅,这里重定向要使用 2> 文件名,比如:

valgrind --leak-check=full ./a.out 2> record.txt

当然了,如果你蛋疼可以这么写:

valgrind --leak-check=full -v --log-fd=1 ./a.out > record.txt

--log-fd=1就是valgrind自己的内部选项,把日志重定向到相应描述符上,先定向到1就是标准输出,然后后面直接使用 >也是可以的,但是。。。。。。。。。。

当然了,还有一种办法就是直接使用文件名的:

valgrind --leak-check=full --log-file=record.txt ./a.out

这样也是输出到那个文件中了,貌似这个多进程的时候更有用,但我还不知道有什么用,看到了再补充。

终于看到是为什么了,这个多进程指定文件后,可以把不同进程的输出到相应的文件中,这样用:

valgrind --leak-check=full --log-file=record.%p ./a.out

这样就是按进程ID来输出到相应的文件中,%p就是进程ID匹配用,但是好像只能是两个进程,多个进程好像只输出

前两个了,还需要进一步使用看看,好了初步学习的记录就到这,要不然太长了。


  1. 写最简单的程序

test.cpp

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    return 0;
}

编译成a.out后,对了,在编译的时候,加上-g,这样在valgrind的信息中会有代码行号等信息,使用valgrind来查看:

valgrind --leak-check=full ./a.out 2> record.txt

==6977== Memcheck, a memory error detector
==6977== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==6977== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==6977== Command: ./a.out
==6977== 
==6977== 
==6977== HEAP SUMMARY:
==6977==     in use at exit: 0 bytes in 0 blocks
==6977==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==6977== 
==6977== All heap blocks were freed -- no leaks are possible
==6977== 
==6977== For counts of detected and suppressed errors, rerun with: -v
==6977== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


上面就是所有输出内容。差不多就这么多。

2. 然后用一个带有没有free或者delete泄漏的。

#include <iostream>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    return 0;
}


使用valgrind查看结果如下:

==7048== Memcheck, a memory error detector
==7048== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7048== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7048== Command: ./a.out
==7048== 
==7048== 
==7048== HEAP SUMMARY:
==7048==     in use at exit: 12 bytes in 1 blocks
==7048==   total heap usage: 1 allocs, 0 frees, 12 bytes allocated
==7048== 
==7048== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7048==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7048==    by 0x4006DC: main (test.cpp:13)
==7048== 
==7048== LEAK SUMMARY:
==7048==    definitely lost: 12 bytes in 1 blocks
==7048==    indirectly lost: 0 bytes in 0 blocks
==7048==      possibly lost: 0 bytes in 0 blocks
==7048==    still reachable: 0 bytes in 0 blocks
==7048==         suppressed: 0 bytes in 0 blocks
==7048== 
==7048== For counts of detected and suppressed errors, rerun with: -v
==7048== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)


这就有问题了,并且告诉的非常明确:

==7048== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7048==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7048==    by 0x4006DC: main (test.cpp:13)

第一行是说:definitely lost (肯定丢了),这是12bytes

第二行是说:调用了new的时候

第三行是说:在调用main()函数的时候

12字节刚好是我们上面定义那个结构体的大小三个int型,12个字节

这样就找到了问题,是new了但是没有delete,然后加上delete后,再运行看结果

==7164== Memcheck, a memory error detector
==7164== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7164== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7164== Command: ./a.out
==7164== 
==7164== 
==7164== HEAP SUMMARY:
==7164==     in use at exit: 0 bytes in 0 blocks
==7164==   total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==7164== 
==7164== All heap blocks were freed -- no leaks are possible
==7164== 
==7164== For counts of detected and suppressed errors, rerun with: -v
==7164== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


又成这样了,说明解决了。这次练习到这里,之后深入学习

3. 下面用了malloc,但是没有free

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    return 0;
}


输出结果是这样的:

==7433== Memcheck, a memory error detector
==7433== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7433== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7433== Command: ./a.out
==7433== 
==7433== 
==7433== HEAP SUMMARY:
==7433==     in use at exit: 24 bytes in 2 blocks
==7433==   total heap usage: 2 allocs, 0 frees, 24 bytes allocated
==7433== 
==7433== 12 bytes in 1 blocks are definitely lost in loss record 1 of 2
==7433==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7433==    by 0x40071C: main (test.cpp:14)
==7433== 
==7433== 12 bytes in 1 blocks are definitely lost in loss record 2 of 2
==7433==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==7433==    by 0x40072A: main (test.cpp:16)
==7433== 
==7433== LEAK SUMMARY:
==7433==    definitely lost: 24 bytes in 2 blocks
==7433==    indirectly lost: 0 bytes in 0 blocks
==7433==      possibly lost: 0 bytes in 0 blocks
==7433==    still reachable: 0 bytes in 0 blocks
==7433==         suppressed: 0 bytes in 0 blocks
==7433== 
==7433== For counts of detected and suppressed errors, rerun with: -v
==7433== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6)

这里就有两个definitely了,这是那个new和malloc都没有释放的原因,最后一句也告诉我们,有两处错误

LEAK SUMMARY:告诉我们,有两个blocks泄漏,共24字节

ERROR SUMMARY:告诉我们,有两处内存肯定泄漏的错误

4. 然后我们进去内存越界访问,先用malloc分配的数组尝试,分配了10个int大小,但是却访问之后的一个int:

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    int *parray = (int *)malloc(10 * sizeof(int));
    parray[10] = 1;
    delete x;
    free(p);
    free(parray);
    return 0;
}

这样会有相应的提示信息告诉我们错误:

==7649== Memcheck, a memory error detector
==7649== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7649== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7649== Command: ./a.out
==7649== 
==7649== Invalid write of size 4
==7649==    at 0x4007D5: main (test.cpp:19)
==7649==  Address 0x4c29108 is 0 bytes after a block of size 40 alloc'd
==7649==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==7649==    by 0x4007C8: main (test.cpp:18)
==7649== 
==7649== 
==7649== HEAP SUMMARY:
==7649==     in use at exit: 0 bytes in 0 blocks
==7649==   total heap usage: 3 allocs, 3 frees, 64 bytes allocated
==7649== 
==7649== All heap blocks were freed -- no leaks are possible
==7649== 
==7649== For counts of detected and suppressed errors, rerun with: -v
==7649== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

错误信息是这样的:Invalid write of size 4

并且告诉我们在main.c的第19行,就是这里我们越界了。

5. 下面我们不用malloc分配,直接在栈上分配,看看越界会不会有提示:

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    int *parray = (int *)malloc(10 * sizeof(int));
    parray[9] = 1;
    delete x;
    free(p);
    free(parray);
    int array[10];
    array[10] = 1;
    return 0;
}


下面是提示信息:

==7765== Memcheck, a memory error detector
==7765== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7765== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7765== Command: ./a.out
==7765== 
==7765== 
==7765== HEAP SUMMARY:
==7765==     in use at exit: 0 bytes in 0 blocks
==7765==   total heap usage: 3 allocs, 3 frees, 64 bytes allocated
==7765== 
==7765== All heap blocks were freed -- no leaks are possible
==7765== 
==7765== For counts of detected and suppressed errors, rerun with: -v
==7765== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

看,这里是没有错误的,所以这种是不提示的,只是分析heap也就是堆上的内存问题的。











你可能感兴趣的:(第一 valgrind初步学习并深入使用)