Как предотвратить утечку unordered_map общих указателей?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как предотвратить утечку unordered_map общих указателей?

Сообщение Anonymous »

Я создаю консольное приложение, в котором использую только интеллектуальные указатели. Я решил использовать только интеллектуальные указатели, чтобы узнать, когда какой интеллектуальный указатель использовать. В этом приложении я пытаюсь использовать шаблон состояний для переключения между различными состояниями. Базовым классом является TurnState, от этого класса наследуют все остальные классы состояний.
В игровом контроллере я определил текущее состояние. Для переключения между состояниями я хочу использовать unordered_map с перечислением в качестве ключа и классом состояния в качестве значения. Но как только я записал std::unordered_map _turn_states_map; внутри заголовка, у меня возникли утечки памяти.
Чтобы получить избавившись от этих утечек памяти, я попытался уничтожить их в деконструкторе следующим образом:

Код: Выделить всё

GameController::~GameController()
{
for (std::unordered_map::iterator iterator{ _turn_states_map.begin() }; iterator != _turn_states_map.end(); iterator++) {
iterator->second.reset();
_turn_states_map.erase(iterator);
}
_turn_states_map.clear();
}
Но и это не вышло. Мне удалось решить эту проблему, используя необработанные указатели, но я пытаюсь достичь не этого. Итак, мой вопрос: как правильно удалить карту с помощью Shared_ptrs?
Будем благодарны за любую помощь.

Редактирование 1 — минимальный пример

Игровой контроллер будет использоваться для сохранения общего_ptr в текущем состоянии и переключения на следующее.< /p>
Ниже находится заголовок GameController:

Код: Выделить всё

class GameController
{
public:
GameController();
~GameController();
void do_action(Socket& client, Player& player, std::string command);
void set_next_state(TurnStateEnum state);

private:
std::unordered_map _turn_states_map;
std::shared_ptr _turn_state;

void initialize_turn_states_map();
};
Ниже приведен исходный код GameController:

Код: Выделить всё

GameController::GameController()
{
initialize_turn_states_map();
_turn_state = _turn_states_map.at(TurnStateEnum::SETUP);
}

GameController::~GameController()
{
for (std::unordered_map::iterator iterator{ _turn_states_map.begin() }; iterator != _turn_states_map.end(); iterator++) {
iterator->second.reset();
_turn_states_map.erase(iterator);
}
_turn_states_map.clear();
}

void GameController::do_action(Socket& client, Player& player, std::string command)
{
_turn_state->do_turn(client, player, command);
}

void GameController::set_next_state(TurnStateEnum state)
{
_turn_state = _turn_states_map.at(state);
}

void GameController::initialize_turn_states_map()
{
_turn_states_map.insert(std::make_pair(TurnStateEnum::SETUP, std::make_shared(*this)));
}
TurnState — это базовый класс. Этот класс должен содержать текущую логику/поведение приложения.
Под заголовком TurnState:

Код: Выделить всё

class GameController;

class TurnState
{
public:
TurnState(GameController& gameCtrl);
virtual ~TurnState();

void next_state(TurnStateEnum stateEnum);
virtual void do_turn(Socket& client, Player& player, std::string command) = 0;
protected:
GameController& _gameCtrl;
};
Под исходным кодом TurnState:

Код: Выделить всё

TurnState::TurnState(GameController& gameCtrl) : _gameCtrl ( gameCtrl )
{
}

TurnState::~TurnState()
{
}

void TurnState::next_state(TurnStateEnum stateEnum)
{
_gameCtrl.set_next_state(stateEnum);
}
Установочное состояние не имеет других переменных или методов, кроме его базового класса, и на данный момент методы пусты.

Редактирование 2 — минимальный пример версии 2

Это может быть лучший минимальный пример. Я создал консольный проект и загрузил его по адресу: https://ufile.io/ce79d

Подробнее здесь: https://stackoverflow.com/questions/426 ... om-leaking
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»