C/C++

C++ и динамическая память: это приемлемо?

В книге Страуструпа, в главе про динамическую память и указатели, он даёт такое задание:

В этой главе ничего не говорилось о том, что произойдет, если, используя оператор new, вы столкнетесь с нехваткой памяти. Это называется исчерпанием памяти (memory exhaustion). Выясните, что случится. У вас есть две очевидные альтернативы: обратиться к документации или написать программу с бесконечным циклом, в котором происходит многократное выделение памяти и не выполняется ее освобождение. Попробуйте оба варианта. Сколько примерно памяти вы сможете выделить, пока она не исчерпается?

Пришёл посоветоваться!
Это приемлемо для проба или компьютер сгорит?
взорвется, расщепится на атомы, создастся черная дыра
Александр Кирьянчук
Александр Кирьянчук
73 465
Лучший ответ
Сергей Вишняков Пробовал. Компьютер отключился в 24 итерации.
Если у вас нет свободных 16 ГБ ОЗУ, используйте такой синтаксис для предотвращения ошибок при нехватке памяти.

int** a = new(nothrow) int* [0xFFFF];
if (a != nullptr) {
for (int i = 0; i < 0xFFFF; ++i) {
a[i] = new(nothrow) int [0xFFFF];
if (a[i] == nullptr) {
for (int j = 0; j < i; ++j) delete[] a[i];
delete[] a;
a = nullptr;
break;
}
}
}
// TODO:
if (a != nullptr) {
for (int i = 0; i < 0xFFFF; ++i) delete[] a[i];
delete[] a;
a = nullptr;
}
Дима Печерский
Дима Печерский
69 880
Не сгорит, сейчас система скажет, что тебе памяти больше не даст - фиг тебе а не память, а когда-то да, аж до вылета системы бывало
Не сгорит. Однако в системах на базе Linux Вас ждет сурприз (опять-же не опасный) =)
Какой - вот сами и попробуйте. Без спойлеров =)

Хинт - поставьте вывод счетчика в цикле.
Указатель вернёт NULL, когда памяти при выделении не хватит
Алексей Рудаков Строго говоря выбросит исключение. Именно поэтому проверка на nullptr не нужна. Кст nullptr

Не выбросит только если указать ...= new (std::nothrow)
Азамат Кожамжаров C++ для ввода/вывода в STDIN и STDOUT, в конечном итоге, использует те же самые системные вызовы что и С. Кто тут и чего имитирует в упор не пойму?
Вадим Марков Так что в итоге, на какое поведение можно точно расчитывать при отсутствии свободной памяти - выбросит исключение или вернет NULL?
Азамат Кожамжаров Я под никсами пишу на С, С++ и иногда, когда торкнет, на Rust и GoLang. И демоны, которые отвязываются от терминала, я тоже писал.
Что касается виндовых ужасов - тут полностью согласен. Последний пример с которым столкнулся - функция rename. Чтобы она под виндой заработала как надо приходится исполнять танец с бубунами из Win32 API
Азамат Кожамжаров https://pastebin.com/dl/J1eTwV9B по этой ссылке его можно просто сразу скачать
Ничего не сгорит, не волнуйтесь.
Недавно случайно сотворил подобную хрень с бесконечным циклом в одной программульке. Система тут же ушла в своп а потом, через некоторое время, зарвавшийся процесс убило ядро.

Вообще же многие вещи из std при ошибке выделения памяти могут выкинуть исключение std::bad_alloc и его полезно перехватывать и обрабатывать.
Думаю, если память исчерпана то программа зависает или ломается. Сколько примерно памяти можно выделить, пока она не исчерпается? Наверное, столько, сколько в компьютере есть свободной и хватает для нормальной работы операционной системы и других программ, включая, IDE. А пробовать, конечно можно - от таких пустяков ничего страшного не должно случиться)