繁体   English   中英

getline()valgrind内存泄漏

[英]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看到对象已被引用,但是,并不是通过指向其基地址的指针“很好地”引用了对象,而是仅通过内部指针。 由于没有指针可用于释放对象,因此似乎有泄漏的可能。

这样的情况可能发生在泄漏程序中:例如,程序分配了一个大对象,然后将其片段(通过指针)分配给其他模块,然后泄漏该大对象。 内部指针确实暗示有泄漏。

可能是getlinebasic::string<>的表示很喜欢,并且做了类似的事情。 复制对象时,新对象不会做任何有趣的事情:它只是通过基地址引用字符串数据。 旧对象消失了,它释放了数据。

只是一个假设。

顺便说一下,在上述程序中,我通过在管理这些数组的矢量对象中保留了指向基地址的额外指针,来修复了Valgrind的问题。 仅当为Valgrind调试构建软件时(与其他功能(例如,使用Valgrind客户端请求API一样)),才会出现此额外的指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM