Я пишу класс (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 для указателя просто нулевым указателем, или он освобождает данные в конце?
Любой совет будет принят во внимание,
Коллин Биденкапп
Нет прямой связи между удалением в вашей программе и его непосредственным отображением, скажем, в диспетчере задач, поскольку ОС пытается оптимизировать использование памяти. Когда вы смотрите в диспетчере задач, вы обычно видите размер рабочего набора вашего приложения, это мера того, сколько памяти запрошено вашим приложением, но не обязательно, сколько оно использует в данный момент.
И на ваш вопрос, да, удаляя память, как вы это делали, это WTG, хотя, как другие отмечали, использование умных указателей, как правило, намного лучше обрабатывает память, чтобы избежать последующих головных болей.
Ты почти прав.
delete this_environment
называет деструктором virtual_flight_runtime_environment
, Деструктор выполняет delete aircraftdata
,
Сразу после этого память занята экземпляром virtual_flight_runtime_environment
выпущен.
Обратите внимание, что delete
оператор не устанавливает указатель на NULL
,
Так что я не вижу проблем в вашем коде, учитывая информацию в вопросе.
Это выглядит правильно.
Вызов delete в вашем this_environment вызовет деструктор этого класса, прежде чем его память будет освобождена. Деструктор удаляет данные самолета. Выглядит правильно.
Вы могли бы рассмотреть вместо того, чтобы иметь переменную-член, содержащую необработанный указатель на aircraftdata вместо этого используя auto_ptr или в с ++ 11 unique_ptr который будет гарантировать, что он будет удален автоматически при создании класса. Ищите это, это не место, чтобы преподавать это, и это просто предложение, а не необходимость.
Редактировать: И я также согласен с комментарием Пита Беккера по этому вопросу, который заключается в том, чтобы спросить, нужен ли вообще указатель.
Вы действительно должны явно назвать «удалить this_environment». В противном случае уничтожается только сам указатель (который существует в стеке). Данные, указанные в куче, все еще будут существовать.
Другое решение — просто избавиться от указателя и объявить вашу переменную как таковую:
virtual_flight_runtime_environment this_environment;
Таким образом, ваш объект будет напрямую существовать в стеке, и его время жизни будет зависеть от области, в которой он объявлен, — и на этом этапе деструктор будет автоматически вызываться, вызывая, в свою очередь, удаление ваших внутренних данных.