Java и C++ по проблеме Раскручивания Стека

Насколько я знаю, в случае неперехваченного исключения, C++ сразу уничтожает локальные переменные, Java выпускает ссылки и оставляет остальных для сборщика "мусора".

Действительно ли это правильно? Каково точно различие между Java и C++ по этой проблеме? другими словами, какой из этих двух языков считают лучше с точки зрения проблемы раскручивания стека?:)

11
задан Feyyaz 31 March 2010 в 08:35
поделиться

4 ответа

Я собираюсь обидеться за это, но ...

C ++ явно лучше, чем Java на фронте раскручивания стека - здесь просто нет соревнования. Деструкторы объектов C ++ срабатывают на всем пути вверх по стеку, пока не будет достигнута точка перехвата, постепенно освобождая все управляемые ресурсы.

Как вы сказали, Java оставляет все это на милость недетерминированного сборщика мусора (в худшем случае) или в руки явно созданных блоков finally, которыми вы засоряли свой код (поскольку Java не поддерживает истинный RAII). То есть весь код управления ресурсами находится в руках клиентов каждого класса, а не в руках конструктора классов, где он должен находиться.

Тем не менее, в C ++ механизм разворачивания стека функционирует должным образом только в том случае, если вы внимательно следите за тем, чтобы сами деструкторы не генерировали исключения. Как только у вас есть два активных исключения, ваша программа abort () работает без передачи go (и, конечно же, без запуска любого из оставшихся деструкторов).

10
ответ дан 3 December 2019 в 06:20
поделиться

Вы совершенно правы, C ++ уничтожает все локальные переменные в обратном порядке при выходе из каждой функции в стеке - точно так же, как если бы вы программно выполняли return - и из main () .

2
ответ дан 3 December 2019 в 06:20
поделиться

Раскрутка стека специально вызывает деструкторы всех полностью сконструированных объектов в цепочке вызовов до точки, где перехватывается исключение.

В Java просто нет раскрутки стека - она ​​ничего не делает с объектами, если генерируется исключение. Вы должны сами обрабатывать объекты в блоках catch и finally . В основном поэтому C # представил с использованием операторов - они упрощают вызов IDisposable.Dispose (), но, опять же, это не полная замена раскрутки стека C ++.

5
ответ дан 3 December 2019 в 06:20
поделиться

Для стека оба варианта одинаковы: они освобождают стек для блоков, которые вы оставляете с исключением. В Java все примитивные типы (int, double и т.д.) сохраняются напрямую, локальные переменные этого типа освобождаются в этот момент. Все объекты сохраняются через ссылки в локальных переменных, поэтому ссылки удаляются, но сами объекты остаются на куче. Если это была последняя ссылка на объект, то они освобождаются при следующей сборке мусора. Если в C++ объекты созданы на куче, а в локальных переменных хранится указатель, то объекты на куче не освобождаются автоматически, они остаются на куче навсегда (да, вы получите MEMORY LEAK). Если вы сохранили объекты на стеке, то вызывается деструктор (и может освободить другие ссылающиеся объекты на куче).

2
ответ дан 3 December 2019 в 06:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: