C++开发使用valgrind memcheck使程序更快更正确
valgrind是提供一系列工具,可以帮助我们是我们的程序更正确,运行的更快,其中比较受欢迎的就是memcheck,接下来是我在这方面的学习总结:
更详细的可以参见:valgrind 用户手册
程序在操作内存时可能犯的错误主要有以下几种:
- 内存泄漏
- 使用未初始化的变量
- 释放内存的方式不对
- 访问了不应该访问的内存
- 内存拷贝移动src和dst存在内存重叠
- 把负值传给内存分配函数
CMakeLists.txt 编写如下:
cmake_minimum_required(VERSION 3.11)
set(CMAKE_CXX_FLAGS "-O2 -g -std=c++11 -pipe -Wall -W -fstrict-aliasing -Wno-invalid-offsetof -Wno-unused-parameter -fno-omit-frame-pointer")
add_executable(memcheck_leak memcheck_leak.cpp)
add_executable(memcheck_uninit memcheck_uninit.cpp)
add_executable(memcheck_errfree memcheck_errfree.cpp)
add_executable(memcheck_visiterr memcheck_visiterr.cpp)
add_executable(memcheck_strncpyerr memcheck_strncpyerr.cpp)
add_executable(memcheck_illegalalloc memcheck_illegalalloc.cpp)
内存泄露 测试代码如下
为了让valgrind的输出结果更加清晰直观,我们编译时加上-g,memcheck_leak.cpp 编写如下:
# memcheck_leak.cpp
#include <iostream>
void leak_mem_func(size_t size) {
auto ptr = new char[size];
(void)ptr;
}
void no_leak_mem_func(size_t size) {
auto ptr = new char[size];
delete[] ptr;
}
int main(int argc, char **argv) {
std::cout << "start ..." << std::endl;
leak_mem_func(10);
no_leak_mem_func(20);
std::cout << "stop ..." << std::endl;
return 0;
}
执行如下命令编译程序
cmake . # 如果没有增删文件,一般只需要执行一次
make
执行程序
正常情况下我们执行程序的命令如下:
# memcheck_leak 为本次测试的编译产出
./memcheck_leak
当使用memcheck时需要执行如下命令:
# 让自己的程序,在valgrind提供的虚拟内核中运行
valgrind --leak-check=yes memcheck_leak
# 执行如上命令后产出如下:
==21928== Memcheck, a memory error detector
==21928== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21928== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==21928== Command: ./memcheck_leak
==21928==
start ...
stop ...
==21928==
==21928== HEAP SUMMARY:
==21928== in use at exit: 10 bytes in 1 blocks
==21928== total heap usage: 2 allocs, 1 frees, 30 bytes allocated #2次内存分配,1次内存释放
==21928==
==21928== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1 #内存泄露的调用栈,以及内存使用场景
==21928== at 0x4C2A8E8: operator new[](unsigned long) (vg_replace_malloc.c:423)
==21928== by 0x4007D4: leak_mem_func (memcheck_test.cpp:4)
==21928== by 0x4007D4: main (memcheck_test.cpp:18)
==21928==
==21928== LEAK SUMMARY: # 对程序的内存泄露情况进行汇总
==21928== definitely lost: 10 bytes in 1 blocks
==21928== indirectly lost: 0 bytes in 0 blocks
==21928== possibly lost: 0 bytes in 0 blocks
==21928== still reachable: 0 bytes in 0 blocks
==21928== suppressed: 0 bytes in 0 blocks
==21928==
==21928== For counts of detected and suppressed errors, rerun with: -v
==21928== ERROR SUMMARY: 1 errors from 1 cont