Подтвердить что ты не робот

С++ vs Java: объекты с бесконечным циклом создают только С++

Это был вопрос в одной из моих книг (без ответа), о котором я думал уже несколько дней. Является ли ответ просто, что код С++ в конечном итоге сбой, потому что он создает ячейку памяти для мусора после каждой итерации?

Рассмотрим следующие фрагменты кода Java и С++, части двух версий приложения на основе графического интерфейса, которое собирает пользовательские настройки и использует их для сборки команды и ее параметров. Метод /function getUserCommandSpecification() возвращает строку, представляющую код команды и ее параметры. Возвращенная строка используется для создания требуемой команды, которая затем выполняется.

Предположим следующее:

(i) После создания в цикле while объекта Command (ссылка на cmd в случае Java или указана cmd в случае С++) ссылка/указатель cmd на сгенерированный объект больше не ссылается или не используется.

(ii) Приложение также определяет команду класса вместе с ее методом/функцией execute().

а. Какая из двух версий кода, подробно описанная ниже, в конечном итоге потерпит крах.
б. Объясните, почему версия программы вылетает, а другая не сбой.

Код Java

...
while (true) {
   String commandSpecification = getUserCommandSpecification();
   Command cmd = new Command(commandSpecification);
   cmd.execute();
}
...

Код С++

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command* cmd = new Command(commandSpecification);
   cmd -> execute();
}
...
4b9b3361

Ответ 1

Да, версия С++ протекает из-за new Command(...) без delete. Конечно, его можно было бы легко кодировать по-разному, чтобы избежать этого:

...
while (true) {
   string commandSpecification = getUserCommandSpecification();
   Command cmd(commandSpecification);
   cmd.execute();
}
...

... поэтому я не уверен, что пример такой же поучительный, как они думают.

Ответ 2

Код С++ создает бесконечное количество объектов Command, которые никогда не удаляются. В С++ нет сборки мусора. Во всех экземплярах, созданных new, нужно вызвать delete.

Ответ 3

Использование исходных указателей выпадает из стиля. Здесь это необязательно, как уже указывалось. В случае, когда указатель действительно нужен, используйте std:: unique_ptr.

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::unique_ptr<Command> cmd(new Command(commandSpecification));
   cmd -> execute();
}

Здесь нет утечки памяти.

Ответ 4

Пример С++ приведет к сбою из-за утечки памяти.

Command* cmd = new Command(commandSpecification);

непрерывно вызывается без соответствующего delete.

Ответ 5

В С++ отсутствует сбор мусора (кроме локалей в пределах области). Таким образом, С++ постоянно выделяет объекты Command в кучу, не освобождая эту память при вызове delete. Таким образом, программа С++ в конечном итоге исчерпает память.

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

Ответ 6

AFAIK, в С++ вам нужно явно уничтожить созданные вами объекты (используя ключевое слово new), в то время как в Java сборщик мусора (который помогает восстановить память, занятую объектами, которые больше недоступны) позаботится об этом для тебя.

В Java объекты, созданные таким образом, будут увеличивать частоту младших GC, поэтому эти объекты, вероятно, даже не попадут в область старого поколения в куче (в зависимости от того, как долго выполняется execute),.

Extreme Performance с Java

Ответ 7

Так как он еще не был явно указан (поиск слова на странице не имеет совпадений), я считаю, что лучше всего добавить: этот код на С++ имеет явную утечку памяти ошибка.

Здесь еще одна рабочая альтернатива, использующая std::auto_ptr (Boost boost::scoped_ptr или Qt QScopedPointer - альтернативные интеллектуальные указатели):

while (true) {
   string commandSpecification = getUserCommandSpecification();
   std::auto_ptr<Command> cmd(new Command(commandSpecification));
   cmd->execute();
}

Ответ 8

прочитал о сборке мусора в java. в java вам не нужно было удалять объекты вручную, потому что jvm делает это за вас автоматически, но в С++ вам нужно удалить объекты, которые вам больше не нужны. также сборщик мусора является полнофункциональным инструментом в java, если вы хотите помочь ему, вы можете сделать ссылку объекта на null после завершения работы.

Object x=new Object()
///
.
.
.
you did your works
x=null;