【问题标题】:Is it memory leak in my code ? Checked with valgrind我的代码中是否存在内存泄漏?用 valgrind 检查
【发布时间】:2020-04-13 09:38:17
【问题描述】:

我有下一个动态分配内存。

//之前

RMIUpStream *rmiUpStream = RMIUpStream::create("RMIResources");

//之后

boost::shared_ptr<RMIUpStream> rmiUpStream(RMIUpStream::create("RMIResources"));

//创建函数

RMIUpStream* RMIUpStream::create(const std::string& rmiResourceString)
{
  RMIUpStream* rmiUpStream = nullptr;

  DEBUG("RMIUpStream::create - ResourceString: "+  rmiResourceString);

  try {
    FileInputStream inCfg(SpecificBoundaryBasics::FILE_NAME_STRING);
    XML::Reader reader(inCfg);

    bool resourcesFound = false;

    while ((reader.getEventType() != XML::Reader::END_DOCUMENT) and (not resourcesFound)) {
      if (reader.getEventType() == XML::Reader::START_TAG) {
        if (reader.getName() == rmiResourceString) {
          resourcesFound = true;
        }
      }
      reader.nextEventType();
    }

    if (resourcesFound) {
      rmiUpStream = new RMIUpStream(rmiResourceString);
      boost::shared_ptr<GeneralRACOONStack::RACOONStackDownStreamBundle> downStreamBundle(
              GeneralRACOONStack::RACOONStackDownStreamBundle::create(*rmiUpStream, rmiResourceString));
      rmiUpStream->setDownStreamBundle(downStreamBundle);
    }
    else {
      throw XML::ValidityViolation("Could not found " + rmiResourceString, reader.getLineNumber());
    }
  }
  catch (XML::Violation& violation) {
    throw ErrorTypes::ResourceError(Outputs::FileParameters(std::string("RMIUpStream.") + SpecificBoundaryBasics::FILE_NAME_STRING,
                                                         violation.getLineNumber(),
                                                         violation.getDetail()));
  }

  return rmiUpStream;
}

我希望在智能指针中分配原始指针会将错误从 valgrind.txt 更改为消失,但不会。

//valgrind.txt

==20363== 32,640 bytes in 1 blocks are possibly lost in loss record 2,403 of 2,406
==20363==    at 0x4028F03: malloc (vg_replace_malloc.c:298)
==20363==    by 0x40C968C: ??? (in /lib/libc-2.9.so)
==20363==    by 0x40C903E: iconv_open (in /lib/libc-2.9.so)
==20363==    by 0x8304484: xercesc_3_1::IconvGNUTransService::IconvGNUTransService(xercesc_3_1::MemoryManager*) (IconvGNUTransService.cpp:450)
==20363==    by 0x822407A: xercesc_3_1::XMLPlatformUtils::makeTransService() (PlatformUtils.cpp:483)
==20363==    by 0x8224391: xercesc_3_1::XMLPlatformUtils::Initialize(char const*, char const*, xercesc_3_1::PanicHandler*, xercesc_3_1::MemoryManager*) (PlatformUtils.cpp:271)
==20363==    by 0x80F77AA: RMIUpStream::RMIUpStream(std::string) (RMIUpStream.cpp:98)
==20363==    by 0x80F80CD: RMIUpStream::create(std::string const&) (RMIUpStream.cpp:68)
==20363==    by 0x810CC8E: main (main.cpp:171)

这只是这种类型的众多标志之一。可能丢失的内存似乎增加了。

【问题讨论】:

  • 你好。内存泄漏检测/日志有时难以阅读。您可能想尝试使用 dr memory (drmemory.org)。
  • 在您的代码中,不清楚谁拥有已使用 new 运算符分配的 rmiUpStream 的所有权。如果您不需要 shared_ptr(每个实例化类只有自己的所有者),您最好使用 std::unique_ptr。这将帮助您确定每个实例化类的所有者。

标签: c++ memory-leaks valgrind


【解决方案1】:

您的内存泄漏警告可能是由创建共享指针可能引发的事实造成的。想象一下,如果有足够的内存来创建 RMIUpStream,但不足以创建共享指针来保存它,会发生什么。 RMIUpStream 对象已创建,但从未绑定到对象。这就是make_shared 存在的原因

详情请见here

---- 更新 ---

如果您没有 make_shared 会怎样?

首先,请注意,这是手工完成的复杂工作,请参见此处。 https://herbsutter.com/gotw/_102/

使用库代码为您执行此操作!

但实际上你的问题可以归结为这行代码......

  rmiUpStream = new RMIUpStream(rmiResourceString); // << not exception safe

除非你把它放在一个智能指针中(比如 unique_ptr),否则抛出的任何异常都会丢失这个内存。 简单地把它放在一个 boost::unique_ptr

【讨论】:

  • 我有旧的boost 版本没有make_shared
  • 我会考虑更新,boost::make_shared 是相当标准的,现在已被 std::make_shared 取代。但是,如果这不可能,只需翻转您的逻辑,因此您首先创建共享指针,然后为其分配“新”的值。我将为您更新示例
猜你喜欢
  • 2013-01-26
  • 2016-08-08
  • 2015-02-28
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多