C ++ / Неправильный ли параметр typedef вызывает утечку памяти? - PullRequest
0 голосов
/ 19 ноября 2018

Неправильный ли параметр typedef вызывает утечку памяти?Следующий код создает утечку памяти

у нас Пример класса A

implA.cpp

void example_funcA(
const std::shared_ptr<A>& object,
const std::function<void(void)>& next) 
{
  ... 
  next(); 
  ...
}

...

void example_funcB(const std::shared_ptr<A>& object)
{...}

implB.cpp / Сначала мы сделали неправильное кодирование. typedef FuncA

auto implA_ = std::make_shared<implA>(.....);
typedef void (implA::*FuncB)(const std::shared_ptr<A>&);

typedef std::function<void(void)> Func;

typedef void (implA::*FuncA)(
      const std::shared_ptr<A>&,
      std::function<void(void)>);

  auto next = (Func)std::bind((FuncB)&implA::example_funcB, implA_, object);

  implA_->async(std::bind((FuncA)&implA::example_funcA, implA_, object, next));

Этот код не может удалить объект класса A с помощью интеллектуального указателя и вызывает утечку памяти.

Но мы изменили код.

typedef void (implA::*FuncA)(
      const std::shared_ptr<A>&,
      std::function<void(void)>);
-> fix code
typedef void (implA::*FuncA)(
      const std::shared_ptr<A>&,
      const std::function<void(void)>&);

Этот код удаляет объект класса А. в виде интеллектуального указателя, который нам нужен.

Суть вопроса в следующем.Влияет ли использование неправильной typedef на счетчик ссылок интеллектуального указателя и возможно ли нехватка памяти в конце операции.

1 Ответ

0 голосов
/ 19 ноября 2018

Вы попали в мир неопределенного поведения.Ваш example_funcA имеет подпись:

  void(const std::shared_ptr<A>&, const std::function<void(void)>&)

, но вы преобразуете его в:

 void(const std::shared_ptr<A>&, std::function<void(void)>)

перед его вызовом.Это заставляет компилятор думать, что ему нужно скопировать второй аргумент, так как он ожидает, что он будет передан по значению, когда действительно example_funcA ожидает ссылку на const.Несоответствие между тем, как компилятор устанавливает (и копирует) аргумент, и тем, что на самом деле ожидает метод, вероятно, приводит к потере копии и, следовательно, к утечке.Поскольку вы привязываете свой shared_ptr к example_funcB, привязка захватывает shared_ptr, и именно этот захват вызывает специфическую утечку.

Как кто-то уже прокомментировал, вы должны избегать приведения в стиле C, поскольку вы не получите никакой защиты от компилятора, использующегоих.Предпочитаю static_cast <> или нет приведения, где вы можете.

...