c++ 代码内存如何校验以及检查

c++ 代码内存如何校验以及检查

本次文章使用 valgrind 对c++ 代码的内存进行校验

1、valgrind 安装

sudo apt install valgrind

2、如何使用 valgrind 对代码进行检查

测试代码:

#include <iostream>  
#include <string>  
#include <memory>
int main(int argc, char** argv){
    std::string arg = argv[1];
    std::cout << "arg=" << arg << std::endl;
    if(arg == "lost_mem"){
        // 内存泄漏
        int *a = new int();
    }
    if(arg == "double_free"){
        // double free
        int * b = new int();
        std::shared_ptr<int> c(b);
        delete b;
    }
    if(arg == "free_stack"){
        // 释放栈空间
        int b;
        int *c = &b;
        delete c;
    }

}

如上代码:
这个测试分别使用3个选项:
lost_mem 测试内存泄漏, 申请了 int 内存未释放

double_free 重复释放:
这里可以看出来 b 给了 shared_ptr, 但是 b 本身有调用了 delete.
所以在 shared_ptr 释放的时候就会导致 重复释放 b

free_stack 释放 栈空间,正常情况下,大部分c++ 程序员都不会犯这个错误,但是如果是使用别人的接口的时候,就有可能造成这个错误。 别人让你传指针,你将栈指针穿进去了,结果别人的代码释放了你穿进去的栈指针,就会出现这个问题。

下面我们看一下每一个的执行结果:
lost_mem

virtual-machine:~/workspace/tmp$ valgrind --leak-check=full ./test lost_mem
==15002== Memcheck, a memory error detector
==15002== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15002== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==15002== Command: ./test lost_mem
==15002== 
arg=lost_mem
==15002== 
==15002== HEAP SUMMARY:
==15002==     in use at exit: 4 bytes in 1 blocks
==15002==   total heap usage: 3 allocs, 2 frees, 73,732 bytes allocated
==15002==  # 注意看这里,报错 test.cpp:9 第9行内存泄漏4个字节
==15002== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==15002==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==15002==    by 0x10A562: main (test.cpp:9)
==15002== 
==15002== LEAK SUMMARY:
==15002==    definitely lost: 4 bytes in 1 blocks
==15002==    indirectly lost: 0 bytes in 0 blocks
==15002==      possibly lost: 0 bytes in 0 blocks
==15002==    still reachable: 0 bytes in 0 blocks
==15002==         suppressed: 0 bytes in 0 blocks
==15002== 
==15002== For lists of detected and suppressed errors, rerun with: -s
==15002== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

double_free

virtual-machine:~/workspace/tmp$ valgrind --leak-check=full ./test double_free
==14672== Memcheck, a memory error detector
==14672== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==14672== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==14672== Command: ./test double_free
==14672== 
arg=double_free
# 注意看这里报错显示 shared_ptr_base.h:348 free 错误,这里没有明确指出错误原因
==14672== Invalid free() / delete / delete[] / realloc()
==14672==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14672==    by 0x10AED7: std::_Sp_counted_ptr<int*, (__gnu_cxx::_Lock_policy)2>::_M_dispose() (shared_ptr_base.h:348)
==14672==    by 0x10ABC6: std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release() (shared_ptr_base.h:168)
==14672==    by 0x10A95A: std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count() (shared_ptr_base.h:705)
==14672==    by 0x10A73D: std::__shared_ptr<int, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr() (shared_ptr_base.h:1154)
==14672==    by 0x10A75D: std::shared_ptr<int>::~shared_ptr() (shared_ptr.h:122)
==14672==    by 0x10A5CF: main (test.cpp:16)
==14672==  Address 0x4de30c0 is 0 bytes inside a block of size 4 free'd
==14672==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14672==    by 0x10A5C3: main (test.cpp:15)
==14672==  Block was alloc'd at
==14672==    at 0x4849013: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==14672==    by 0x10A590: main (test.cpp:13)
==14672== 
==14672== 
==14672== HEAP SUMMARY:
==14672==     in use at exit: 0 bytes in 0 blocks
==14672==   total heap usage: 4 allocs, 5 frees, 73,756 bytes allocated
==14672== 
==14672== All heap blocks were freed -- no leaks are possible
==14672== 
==14672== For lists of detected and suppressed errors, rerun with: -s
==14672== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

free_stack

virtual-machine:~/workspace/tmp$ valgrind --leak-check=full ./test free_stack
==15203== Memcheck, a memory error detector
==15203== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==15203== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==15203== Command: ./test free_stack
==15203== 
arg=free_stack
# 注意看这里, test.cpp:21 free 错误,同样没有明确指出错误原因,这个就需要大家自己去研究原因了
==15203== Invalid free() / delete / delete[] / realloc()
==15203==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==15203==    by 0x10A607: main (test.cpp:21)
==15203==  Address 0x1ffefffd90 is on thread 1's stack
==15203==  in frame #1, created by main (test.cpp:4)
==15203== 
==15203== 
==15203== HEAP SUMMARY:
==15203==     in use at exit: 0 bytes in 0 blocks
==15203==   total heap usage: 2 allocs, 3 frees, 73,728 bytes allocated
==15203== 
==15203== All heap blocks were freed -- no leaks are possible
==15203== 
==15203== For lists of detected and suppressed errors, rerun with: -s
==15203== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

以上就是个人的一些小心得

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值