LINUX.ORG.RU

Можно ли узнать о том, что закончилась память в с++ на практике?

 , , ,


0

2

По стандарту, это можно, но вот на практике у меня на Убунту 13.04 и g++ 4.7.3 следующая программа просто убивается (ядром как я понимаю). Я же расчитывал что по коду возврата смогу понять, что именно происходит, но код возврата всегда равен 137. Заранее благодарю.

#include <iostream>
#include <new>
#include <cstdlib>

void no_more_ram()
{
	exit(3);
}

int main()
{
	std::set_new_handler(no_more_ram);
	std::cout << "!!!Hello World!!!" << std::endl; // prints !!!Hello World!!!

	try
	{
		while (true)
		{
			int* p= new int[1024 * 1024];
			if (!p)
			{
				exit(4);
			}
		}
	} catch (const std::bad_alloc& ex)
	{
		return 1;
	} catch (...)
	{
		return 2;
	}

	return 0;
}

Хочешь узнать когда ПРИДЕТ ВРЕМЯ ОСВОБОЖДАТЬ ПАМЯТЬ?

anonymous
()

Нужно смотреть по какой причине прибили (в dmesg, например). Скорее всего процесс убил OOM киллер и от него не спрячешься.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)

А если сделать sysctl -w vm.overcommit_memory=2? Тогда ядро будет применять не оптимистичную политику выделения памяти (прибивая программы по OOM, когда они пытаются писать в выделенные куски памяти, которая закончилась), а захватывать её сразу (тогда malloc точно не сработает, если памяти не будет).

AITap ★★★★★
()

По стандарту, это можно

Неужели? А я то думал, что по стандарту можно только если узнать, что память выделить не удалось, но программа работает дальше. Никто не гранатирует, и стандарт вообще не касается того, что ОС не грохнет вашу программу без всяких предупреждений, если станет мало памяти. Причем произойти это может и не по вине вашей вашей программы.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

В ядре 3.10 добавили: «В cgroups добавлена поддержка генерации события с уведомлением приложения о приближении к исчерпанию доступной процессу или системе памяти»

anonymous
()

Если надо по простому, то достаточно выделять память бОльшими кусками (например, по 10 МиБ или больше) и сигнал завершения, про который уже написали, не будет послан.

xaizek ★★★★★
()

если делать memset то могут и раньше прибить

ihanick
()

По стандарту, это можно

4.2

в стандарте это не определено. Для x86 это тоже не определено. Памяти у тебя ровно 18446744073709551616 байт(у тебя же amd64?).

drBatty ★★
()
Ответ на: комментарий от no-such-file

Из этого примера видно, что нельзя:

А я то думал, что по стандарту можно только если узнать, что память выделить не удалось

Насколько я понимаю ОС убивает программу и никакие стандартные средства не говорят, что память выделить не удалось. Это на Убунту меня сильно печалит, т.к. под IOS я получал предупреждения о нехватке памяти.

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

leanid-chaika
() автор топика
Ответ на: комментарий от AITap

А если сделать

То тогда срочно придётся идти в магазин за памятью.

anonymous
()
Ответ на: комментарий от xaizek

Благодарю! Сработало, 10Мб - не сработало, но на 32Мб действительно попал в обработчик, нехватки памяти.

Но этот способ не идеален, т.к. тогда придется писать собственный менеджер памяти...

leanid-chaika
() автор топика
Ответ на: комментарий от leanid-chaika

Я не предлагал это как решение, просто как способ заставить пример выдавать ожидаемое поведение. По нормальному, надо настраивать окружение, чтобы оно не убивало процесс в такой ситуации и тогда стандартная библиотека C++ будет вести себя как ожидается.

xaizek ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.