Дружит ли placement new c std::nothrow?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Absurd писал(а):На win64 верхний предел динамической памяти выделяемой для процесса это 8TB,
8ТБ - это 43 бита, ни как не 64. Аналогично, кстати, на x86_32 разрешено выделять только 2ГБ на процесс, что соответствует 31-му биту. Адресное пространство то больше, 2 в степени 64=18446744073709551616.
Absurd писал(а):Ну Ок, уговорил, разрешаю тебе ловить std::bad_alloc. Но вот такой вопрос: к примеру, ты компилируешь огромный исходник на С++ с кучей темплейтов и пр. Когда попытался аллокировать память для того чтобы раскрыть какой-то шаблон с новыми параметрами получил внезапно std::bad_alloc. Вопрос: как продолжать дальше работать.
А почему этот вопрос ко мне то? Оно по факту бросается, причём, при 8-ми ГБ уже при

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

int *Array;
Array=(int*)(operator new [](20000000000*sizeof(int));
. И я не писал ни систему, ни стандарт c++. И если прибивать чемпиона, то как этому чемпиону потом работать? Кроме того, если прибивать чемпиона, то как ему дальше работать? А вот если исключение, то можно его поймать, вывести сообщение и дальше пусть пользователь решает, что ему приоритетнее. Может ему как раз оракл не нужен и он имеет полномочия прибить его? Он его и прибьёт, а потом даст команду повторить попытку выделения памяти. Оракл, кстати, - такое же приложение. А если прибить, процесс ведь даже не сможет сказать, почему и дать рекомендации, а система на это не способна в принципе. Ну скажет она про перерасход памяти. А какие опции приложения в этом виновны? Она сама об этом не догадывается.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Что-то про шаблон я не понял. Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.

А вот вопрос о том, как должно реагировать приложение на то, что ему не дали столько динамической памяти, сколько оно захотело, действительно интересен. В подавляющем случае программ (думаю, как и в случае программы, которую пишет Сионист), должно завершаться. Так что в хорошо спроектированном приложении в этом случае нужен всего один catch в main, который обработает эту ситуацию, тем самым не дав программе "скрашиться" на unhandled exception. Иными словами, везде, где мы делаем new сразу же ловить bad_alloc, как минимум, некрасиво.

Однако есть программы с интеллектуальными алгоритмами аллоцирования, у которых логика может быть завязана на то, полетел ли bad_alloc или нет. Например такие программы, который просят дать столько-то памяти, а если не смогли, то просят меньше и работают с меньшей памятью за счёт в ущерб скорости.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Romeo писал(а):Что-то про шаблон я не понял. Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.
new может быть завёрнут в функцию-член, оператор-член и даже в друга любого класса, в том числе шаблонного. Я к этому члену/другу обращусь как раз в рантайме, а он бросит исключение. Поймаю и обработаю в своём коде и всего делов. Но в данном случае мне нужна реакция в той же функции, которая непосредственно содержит и оператор new. И даже не выше по уровню вложения альтернатив, свичей и циклов. В этом случае проще поймать nullptr, а исключение предназначено для передачи ошибки через уровни вызовов/вложений в другое место в программе. Когда сторонний код не смог выделить память и не знает, как именно должен на это реагировать, он просто выдаёт исключение вызывающему, а тот уже будет разбираться. А тут выделяет свой код и может быть востребована как аналогичная передача наверх, так и реакция на ошибку в месте её возникновения. Мне надо в месте возникновения.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Сионист писал(а):8ТБ - это 43 бита, ни как не 64. Аналогично, кстати, на x86_32 разрешено выделять только 2ГБ на процесс, что соответствует 31-му биту. А почему этот вопрос ко мне то?
в x86_64 (sizeof(void*)*CHAR_BITS) == 64

BTW, код-то пишешь ты и решения о дизайне принимаешь ты. По мне так единственный разумный путь это в случае неожиданной неудачи это вызвать что-то типа panic("Can't allocate memory") и убить текущий процесс. Если подходить серьезно, то в функции panic() можно сохранить трупик процесса на диск, чтобы можно было сделать вскрытие и определить кто же там умудрился запросить у ОС массив на несколько ГБ. Это позволит сконцентрироваться на нормальных сценариях работы и избежать оверинжинеринга.
Сионист писал(а):Может ему как раз оракл не нужен и он имеет полномочия прибить его? Он его и прибьёт, а потом даст команду повторить попытку выделения памяти. Оракл, кстати, - такое же приложение. А если прибить, процесс ведь даже не сможет сказать, почему и дать рекомендации, а система на это не способна в принципе. Ну скажет она про перерасход памяти. А какие опции приложения в этом виновны? Она сама об этом не догадывается.

Ну это ты изобретаешь подход Windows (диалоговое окно "windows is going low on memory") Только к моменту появления такого диалога немного памяти еще есть. Если ее нет, то можно попасть в ситуацию когда недостаточно памяти чтобы показать подобное диалоговое окно. Тогда единственный путь - принять решение автоматически.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.
Если ты пишешь компилятор С++, то тебе придется раскрывать шаблоны чужих программ в рантайме.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Romeo писал(а):Так что в хорошо спроектированном приложении в этом случае нужен всего один catch в main, который обработает эту ситуацию, тем самым не дав программе "скрашиться" на unhandled exception.

catch размотает стек и мы потеряем контекст в котором произошла ошибка.
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Absurd писал(а):Если ты пишешь компилятор С++, то тебе придется раскрывать шаблоны чужих программ в рантайме.
Не думал, что в качестве примера пользовательской программы выбран компилятор языка С++ :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Absurd писал(а):catch размотает стек и мы потеряем контекст в котором произошла ошибка.
Это в том случае, если он нужен. Я же написал, что большинству программ он как раз не нужен. Если не хватило памяти, они просто должны завершить работу.

Про те программы, которым контекст такой ошибки необходим, я написал отдельно.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Romeo писал(а):Не думал, что в качестве примера пользовательской программы выбран компилятор языка С++ :)

Первое что пришло в голову когда подумал о программе очень активно использующей динамическую память, причем использующей только мелкие объекты и массивы размером по 16-128 байт создание которых размазано по всему проекту и не поддается никакой локализации. Другой пример - веб браузер, пожалуй. В базах данных память выделяется сразу несколькими большими кусками, причем их размер конфигурируется пользователем.

BTW, clang - очень интересный проект. Компилятор С++, полностью поддерживает стандарт, собирается 2015-й вижуалкой. Строки "bad_alloc" я в ихних исходниках не нашел. Ни в парсере исходного кода, ни в оптимизаторе, ни в генераторе объектного кода, ни в линкере. Но она должна быть где-то в исходниках CRT, конечно.
2B OR NOT(2B) = FF
Ответить