由于想尝试去检测内存泄漏,因此使用了最常见的工具Valgrind。
方法
执行以下命令即可,将输出的log进行重定位,执行对应可执行程序
valgrind --tool=memcheck --leak-check=full --log-file=valgrind.log ./build/bin/suffix data/test2.fa输出
显示使用了Memcheck工具,用于检测内存,是一个Valgrind自带的工具,以及运行的指令和Parend PID
==139216== Memcheck, a memory error detector
==139216== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==139216== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==139216== Command: ./build/bin/suffix data/test2.fa
==139216== Parent PID: 133038根据询问Qwen2.5-Max,我们可以得出Memcheck有以下功能
- 检测未初始化的内存访问 (如使用未初始化的变量)
- 检测内存越界访问 (如数组越界、缓冲区溢出)
- 检测内存泄漏 (如未释放的
malloc/new分配的内存) - 检测重复释放
(double free)或非法释放(如释放栈内存)
以下是实际的检测结果
==139216== Warning: set address range perms: large range [0x5210040, 0x40bbce2c) (undefined)
==139216== Invalid read of size 4
==139216== at 0x114ACC: SuffixAutomation::judge_len_range(int, int) (in /home/hasee/bio/code/suffix/build/bin/suffix)
==139216== by 0x114BF4: void SuffixAutomation::get_right_index(int)::{lambda(auto:1&&, int)#1}::operator()<{lambda(auto:1&&, int)#1}&>({lambda(auto:1&&, int)#1}&, int) const (in /home/hasee/bio/code/suffix/build/bin/suffix)
==139216== by 0x114978: SuffixAutomation::get_right_index(int) (in /home/hasee/bio/code/suffix/build/bin/suffix)
==139216== by 0x120950: solve(std::basic_ofstream<char, std::char_traits<char> >&, unsigned char*, int, Param const&) (in /home/hasee/bio/code/suffix/build/bin/suffix)
==139216== by 0x1139FD: main (in /home/hasee/bio/code/suffix/build/bin/suffix)
==139216== Address 0x4114e33c is 4 bytes before a block of size 262,144 alloc'd
可以发现展开了整个调用栈,错误是读取了一个分配好的Block之前的4个字节,因此导致了越界,最后还说明了是分配的位置是一个大小为262144字节的vector。
接着可以查看对于内存泄漏的检测
==1079975== Memcheck, a memory error detector
==1079975== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==1079975== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info
==1079975== Command: ./build/bin/suffix data/test2.fa
==1079975== Parent PID: 133038
==1079975==
==1079975== Warning: set address range perms: large range [0x5210040, 0x40bbce2c) (undefined)
==1079975==
==1079975== HEAP SUMMARY:
==1079975== in use at exit: 1,000,001,476 bytes in 2 blocks
==1079975== total heap usage: 188,348 allocs, 188,346 frees, 1,019,210,874 bytes allocated
==1079975==
==1079975== 1,000,001,004 bytes in 1 blocks are possibly lost in loss record 2 of 2
==1079975== at 0x4846FA3: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1079975== by 0x10BC0A: return_read(_IO_FILE*) (in /home/hasee/bio/code/suffix/build/bin/suffix)
==1079975== by 0x11391E: main (in /home/hasee/bio/code/suffix/build/bin/suffix)
==1079975==
==1079975== LEAK SUMMARY:
==1079975== definitely lost: 0 bytes in 0 blocks
==1079975== indirectly lost: 0 bytes in 0 blocks
==1079975== possibly lost: 1,000,001,004 bytes in 1 blocks
==1079975== still reachable: 472 bytes in 1 blocks
==1079975== suppressed: 0 bytes in 0 blocks
==1079975== Reachable blocks (those to which a pointer was found) are not shown.
==1079975== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1079975==
==1079975== For lists of detected and suppressed errors, rerun with: -s
==1079975== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
经过GPT的解析,可以发现这里检测数量内存泄漏,一共进行了188,348次内存分配和188,346次内存释放,总共分配了1,019,210,87字节,说明有两次内存分没有释放。
而后还说明了内存泄露的具体情况:
- 可能泄漏
(possibly lost): 1,000,001,004字节(接近1GB) - 泄漏发生在return_read(_IO_FILE*) 函数中
- 调用堆栈:
main函数 -> return_read函数 -> operator new
于是找到对应函数进行查看内存释放情况即可。