Это утечка памяти в моем коде? Проверено с Valgrind - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть следующая динамическая c память выделения.

// до

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)

Это только один из многих логотипов этого типа. Возможно, память, которая может быть потеряна, увеличивается.

1 Ответ

0 голосов
/ 13 апреля 2020

Ваше предупреждение об утечке памяти, вероятно, связано с тем, что может создать общий указатель. Представьте себе, что происходит, если достаточно памяти для создания RMIUpStream, но недостаточно для создания общего указателя для его хранения. Объект RMIUpStream создается, но никогда не привязывается к объекту. Вот почему make_shared существует

Подробнее см. здесь

---- ОБНОВЛЕНИЕ ---

Что произойдет, если у вас нет make_shared?

Во-первых, имейте в виду, что это сложная вещь, которую нужно делать вручную, смотрите здесь. https://herbsutter.com/gotw/_102/

Используйте библиотечный код, чтобы сделать это за вас!

Но на самом деле вашу проблему можно свести к этой строке кода ...

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

Если вы не укажете это в умном указателе (например, unique_ptr), любое выброшенное исключение потеряет эту память. Просто поместите это в повышение :: unique_ptr

...