[英]getline() valgrind memory leak
我的getline发生内存泄漏,我不确定为什么或如何停止它。
这是valgrind的报告:
==26681==
==26681== HEAP SUMMARY:
==26681== in use at exit: 1,756 bytes in 73 blocks
==26681== total heap usage: 223 allocs, 150 frees, 15,523 bytes allocated
==26681==
==26681== 28 bytes in 1 blocks are possibly lost in loss record 1 of 4
==26681== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==26681== by 0x4CCC4B8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (new_allocator.h:94)
==26681== by 0x4CCD227: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (basic_string.tcc:631)
==26681== by 0x4CCD30F: std::string::reserve(unsigned long) (basic_string.tcc:512)
==26681== by 0x4CCD5D4: std::string::append(char const*, unsigned long) (basic_string.tcc:310)
==26681== by 0x4C86384: std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) (istream.cc:397)
==26681== by 0x4026ED: main (test.cpp:210)
==26681==
==26681== LEAK SUMMARY:
==26681== definitely lost: 0 bytes in 0 blocks
==26681== indirectly lost: 0 bytes in 0 blocks
==26681== possibly lost: 28 bytes in 1 blocks
==26681== still reachable: 1,728 bytes in 72 blocks
==26681== suppressed: 0 bytes in 0 blocks
==26681== Reachable blocks (those to which a pointer was found) are not shown.
==26681== To see them, rerun with: --leak-check=full --show-reachable=yes
==26681==
==26681== For counts of detected and suppressed errors, rerun with: -v
==26681== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)
这是test.cpp的第210行
bool pending = getline(inputfile, line);
其他几行:
string line;
bool pending = getline(inputfile, line);
int round = readOption(inputfile);
int num = readOption(inputfile);
我认为它与getline失败有关,并且因为line是一个string
因此它从不以某种方式永远不会释放该内存。 我该如何预防?
readOption也使用getline
但是我认为它没有内存泄漏,因为string line
是在本地定义的,然后超出范围,有效地清理了内存?
编辑1:
我通过创建一个虚拟函数来“解决”了这个问题:
bool getnewline(ifstream &inputfile) {
string line;
return getline(inputfile, line);
}
但是这样做似乎很愚蠢,我不确定为什么valgrind会抱怨没有泄漏。 对于这个问题,我仍在寻求更好/干净的解决方案。
当通过调用exit()
函数退出C ++程序时,将不运行对象析构函数。 这可能导致Valgrind报告内存泄漏。
我知道这已经快一年了,但是我遇到了这个答案,它专门针对getline()内存泄漏问题,并希望就如何重现此特定问题给出最低限度的指导,因为我认为这只是定义一个std :: string变量,不能从程序中干净退出。
给定以下内容:
Leaky.cpp:
#include <iostream>
int main(int argc, char ** argv) {
std::string x = "x";
exit(1);
return 0;
}
编译字符串:
g++ -g -Wall -Wpedantic --std=gnu++11 leaky.cpp -o leaky
Valgrind调用:
valgrind --tool=memcheck --leak-check=full ./leaky
这样做将表明确实存在泄漏:
==4434== Memcheck, a memory error detector
==4434== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4434== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==4434== Command: ./leaky
==4434==
==4434==
==4434== HEAP SUMMARY:
==4434== in use at exit: 16 bytes in 1 blocks
==4434== total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==4434==
==4434== 16 bytes in 1 blocks are possibly lost in loss record 1 of 1
==4434== at 0x402A6DC: operator new(unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4434== by 0x40F8213: std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==4434== by 0x40FA125: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==4434== by 0x40FA7AF: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.19)
==4434== by 0x804875E: main (leaky.cpp:3)
==4434==
==4434== LEAK SUMMARY:
==4434== definitely lost: 0 bytes in 0 blocks
==4434== indirectly lost: 0 bytes in 0 blocks
==4434== possibly lost: 16 bytes in 1 blocks
==4434== still reachable: 0 bytes in 0 blocks
==4434== suppressed: 0 bytes in 0 blocks
==4434==
==4434== For counts of detected and suppressed errors, rerun with: -v
==4434== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
据我所知,当然要尝试包含问题的答案,exit(1)会强制程序退出而不调用任何析构函数,据我所知,我只使用C ++一个半月,所以我并不是真正的专家。
可能有问题的C ++类正在使用指针进行某些操作,这些指针暗示了Valgrind可能存在泄漏行为。
我在分配一些数组的项目中对此进行了诊断,但是随后我将指针调整到第三个元素,以便使用索引[-2]和[-1]来存储一些元信息。 没有泄漏,因为我还原了指针并正确释放了数组。
Valgrind看到对象已被引用,但是,并不是通过指向其基地址的指针“很好地”引用了对象,而是仅通过内部指针。 由于没有指针可用于释放对象,因此似乎有泄漏的可能。
这样的情况可能发生在泄漏程序中:例如,程序分配了一个大对象,然后将其片段(通过指针)分配给其他模块,然后泄漏该大对象。 内部指针确实暗示有泄漏。
可能是getline
用basic::string<>
的表示很喜欢,并且做了类似的事情。 复制对象时,新对象不会做任何有趣的事情:它只是通过基地址引用字符串数据。 旧对象消失了,它释放了数据。
只是一个假设。
顺便说一下,在上述程序中,我通过在管理这些数组的矢量对象中保留了指向基地址的额外指针,来修复了Valgrind的问题。 仅当为Valgrind调试构建软件时(与其他功能(例如,使用Valgrind客户端请求API一样)),才会出现此额外的指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.