unique_ptr сообщение об ошибке двойного удаления - PullRequest
0 голосов
/ 04 ноября 2019

После компиляции этого фрагмента кода я получаю сообщения об ошибках, которые указывают, что происходит двойное удаление;мой вопрос, что именно не так с этим кодом? Где возникает проблема?

#include <iostream>
#include <memory>

class Manager;

class Interface {
protected:
  friend class InputListener;
  bool flag_;
};

class InputListener {
public:
  InputListener(std::shared_ptr<Interface> manager_ptr) {
    manager_ptr_ = std::move(manager_ptr);
    std::async(std::launch::async, &InputListener::Run, this);
  }

  void Run() {
    char c;
    std::cin >> c;
    manager_ptr_->flag_ = true;
  }

private:
  std::shared_ptr<Interface> manager_ptr_;
};

class Manager : public Interface {
public:
  Manager()
      : listener_ptr_{
            std::make_unique<InputListener>(std::shared_ptr<Manager>(this))} {}

  void Run() {
    while (true) {
      if (Interface::flag_)
        break;
    }
  }

private:
  std::unique_ptr<InputListener> listener_ptr_;
};

int main() {
  Manager m;
  m.Run();
  return 0;
}

Почему этот код вызывает эту ошибку? munmap_chunk (): неверный указатель прерван (ядро выгружено)

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

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

0 голосов
/ 04 ноября 2019

Здесь вы передаете shared_ptr 'this' во время конструктора ....

  Manager()
      : listener_ptr_{
            std::make_unique<InputListener>(std::shared_ptr<Manager>(this))} {}

Однако 'this' объявлено в куче:

  Manager m;

Это будетвызвать проблему при вызове dtor для InputListener. Может быть, рассмотреть возможность изменения manager_ptr_ для слабого_птр, если это предназначение для класса?

...