Деструкторы класса и освобождение указателя

Я пишу класс (virtual_flight_runtime_environment), и он в основном не является статическим, за исключением одной статической функции для целей потока Win32, использующего его в качестве своей функции. Класс объявляет struct simaircraftdata * aircraftdata (структура данных) и вызывает ‘aircraftdata = new aircraftdata;’ в конструкторе (public: virtual_flight_runtime_environment ()).

Мой вопрос о деструкторах и освобождении памяти. Я написал деструктор так:

    ~virtual_flight_runtime_environment(void) {
/*..Other code, i.e. closing win32 handles, etc.*/
delete aircraftdata;
}

Теперь класс объявлен в другой функции (функция DoWork фонового рабочего .Net), например:

    virtual_flight_runtime_environment* this_environment = new virtual_flight_runtime_environment;

И как раз перед концом функции я вызываю ‘delete this_environment;’. Сразу после этого ‘this_environment’ вышел бы из области видимости, и должен был быть вызван разрушитель.

Это правильно? Я заметил постоянное увеличение использования памяти с течением времени, и мне интересно, сделал ли я что-то не так. Делает ли вызов delete для указателя просто нулевым указателем, или он освобождает данные в конце?

Любой совет будет принят во внимание,

Коллин Биденкапп

1

Решение

Нет прямой связи между удалением в вашей программе и его непосредственным отображением, скажем, в диспетчере задач, поскольку ОС пытается оптимизировать использование памяти. Когда вы смотрите в диспетчере задач, вы обычно видите размер рабочего набора вашего приложения, это мера того, сколько памяти запрошено вашим приложением, но не обязательно, сколько оно использует в данный момент.

И на ваш вопрос, да, удаляя память, как вы это делали, это WTG, хотя, как другие отмечали, использование умных указателей, как правило, намного лучше обрабатывает память, чтобы избежать последующих головных болей.

1

Другие решения

Ты почти прав.

delete this_environment называет деструктором virtual_flight_runtime_environment, Деструктор выполняет delete aircraftdata,

Сразу после этого память занята экземпляром virtual_flight_runtime_environment выпущен.

Обратите внимание, что delete оператор не устанавливает указатель на NULL,

Так что я не вижу проблем в вашем коде, учитывая информацию в вопросе.

1

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

Вы могли бы рассмотреть вместо того, чтобы иметь переменную-член, содержащую необработанный указатель на aircraftdata вместо этого используя auto_ptr или в с ++ 11 unique_ptr который будет гарантировать, что он будет удален автоматически при создании класса. Ищите это, это не место, чтобы преподавать это, и это просто предложение, а не необходимость.

Редактировать: И я также согласен с комментарием Пита Беккера по этому вопросу, который заключается в том, чтобы спросить, нужен ли вообще указатель.

1

Вы действительно должны явно назвать «удалить this_environment». В противном случае уничтожается только сам указатель (который существует в стеке). Данные, указанные в куче, все еще будут существовать.

Другое решение — просто избавиться от указателя и объявить вашу переменную как таковую:

virtual_flight_runtime_environment this_environment;

Таким образом, ваш объект будет напрямую существовать в стеке, и его время жизни будет зависеть от области, в которой он объявлен, — и на этом этапе деструктор будет автоматически вызываться, вызывая, в свою очередь, удаление ваших внутренних данных.

0