Страница 2 из 2
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 15:58
Сионист
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++. И если прибивать чемпиона, то как этому чемпиону потом работать? Кроме того, если прибивать чемпиона, то как ему дальше работать? А вот если исключение, то можно его поймать, вывести сообщение и дальше пусть пользователь решает, что ему приоритетнее. Может ему как раз оракл не нужен и он имеет полномочия прибить его? Он его и прибьёт, а потом даст команду повторить попытку выделения памяти. Оракл, кстати, - такое же приложение. А если прибить, процесс ведь даже не сможет сказать, почему и дать рекомендации, а система на это не способна в принципе. Ну скажет она про перерасход памяти. А какие опции приложения в этом виновны? Она сама об этом не догадывается.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 16:03
Romeo
Что-то про шаблон я не понял. Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.
А вот вопрос о том, как должно реагировать приложение на то, что ему не дали столько динамической памяти, сколько оно захотело, действительно интересен. В подавляющем случае программ (думаю, как и в случае программы, которую пишет Сионист), должно завершаться. Так что в хорошо спроектированном приложении в этом случае нужен всего один catch в main, который обработает эту ситуацию, тем самым не дав программе "скрашиться" на unhandled exception. Иными словами, везде, где мы делаем new сразу же ловить bad_alloc, как минимум, некрасиво.
Однако есть программы с интеллектуальными алгоритмами аллоцирования, у которых логика может быть завязана на то, полетел ли bad_alloc или нет. Например такие программы, который просят дать столько-то памяти, а если не смогли, то просят меньше и работают с меньшей памятью за счёт в ущерб скорости.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 16:15
Сионист
Romeo писал(а):Что-то про шаблон я не понял. Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.
new может быть завёрнут в функцию-член, оператор-член и даже в друга любого класса, в том числе шаблонного. Я к этому члену/другу обращусь как раз в рантайме, а он бросит исключение. Поймаю и обработаю в своём коде и всего делов. Но в данном случае мне нужна реакция в той же функции, которая непосредственно содержит и оператор new. И даже не выше по уровню вложения альтернатив, свичей и циклов. В этом случае проще поймать nullptr, а исключение предназначено для передачи ошибки через уровни вызовов/вложений в другое место в программе. Когда сторонний код не смог выделить память и не знает, как именно должен на это реагировать, он просто выдаёт исключение вызывающему, а тот уже будет разбираться. А тут выделяет свой код и может быть востребована как аналогичная передача наверх, так и реакция на ошибку в месте её возникновения. Мне надо в месте возникновения.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 16:27
Absurd
Сионист писал(а):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") Только к моменту появления такого диалога немного памяти еще есть. Если ее нет, то можно попасть в ситуацию когда недостаточно памяти чтобы показать подобное диалоговое окно. Тогда единственный путь - принять решение автоматически.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 16:29
Absurd
Инстанцирование шаблона происходит во время компиляции, а new вызывается в рантайме.
Если ты пишешь компилятор С++, то тебе придется раскрывать шаблоны чужих программ в рантайме.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 17 ноя 2015, 16:34
Absurd
Romeo писал(а):Так что в хорошо спроектированном приложении в этом случае нужен всего один catch в main, который обработает эту ситуацию, тем самым не дав программе "скрашиться" на unhandled exception.
catch размотает стек и мы потеряем контекст в котором произошла ошибка.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 18 ноя 2015, 11:03
Romeo
Absurd писал(а):Если ты пишешь компилятор С++, то тебе придется раскрывать шаблоны чужих программ в рантайме.
Не думал, что в качестве примера пользовательской программы выбран компилятор языка С++

Re: Дружит ли placement new c std::nothrow?
Добавлено: 18 ноя 2015, 11:05
Romeo
Absurd писал(а):catch размотает стек и мы потеряем контекст в котором произошла ошибка.
Это в том случае, если он нужен. Я же написал, что большинству программ он как раз не нужен. Если не хватило памяти, они просто должны завершить работу.
Про те программы, которым контекст такой ошибки необходим, я написал отдельно.
Re: Дружит ли placement new c std::nothrow?
Добавлено: 18 ноя 2015, 11:24
Absurd
Romeo писал(а):Не думал, что в качестве примера пользовательской программы выбран компилятор языка С++
Первое что пришло в голову когда подумал о программе очень активно использующей динамическую память, причем использующей только мелкие объекты и массивы размером по 16-128 байт создание которых размазано по всему проекту и не поддается никакой локализации. Другой пример - веб браузер, пожалуй. В базах данных память выделяется сразу несколькими большими кусками, причем их размер конфигурируется пользователем.
BTW, clang - очень интересный проект. Компилятор С++, полностью поддерживает стандарт, собирается 2015-й вижуалкой. Строки "bad_alloc" я в ихних исходниках не нашел. Ни в парсере исходного кода, ни в оптимизаторе, ни в генераторе объектного кода, ни в линкере. Но она должна быть где-то в исходниках CRT, конечно.