C ++ Vector улавливает изменение размера утечки памяти

Я пытаюсь сохранить вектор, полный указателя на объекты Circle.
Иногда ловушка bad_alloc работает, но иногда нет, тогда я получаю сообщение об ошибке:

Это приложение запросило Runtime прекратить его необычным способом.
Пожалуйста, обратитесь в службу поддержки приложения для получения дополнительной информации. «

Возможно, векторный массив не может выделить больше памяти … Но bad_alloc не может его перехватить.

Circle *ptr;
vector<Circle*> ptrarray;

try{
for (long long i = 0; i < 80000000; i++) {
ptr = new Circle(1,i);
ptrarray.push_back(ptr);
}
}catch(bad_alloc &ba){
cout << "Memory Leak" << endl;
}

Было бы здорово, если бы кто-то мог мне помочь;)
заранее спасибо

2

Решение

Многие операционные системы позволяют процессам запрашивать больше виртуальных адресов (номинально доступной памяти), чем у него есть виртуальная память для поддержки, при условии, что процессы могут фактически не обращаться ко всем страницам. Известно, что это позволяет использовать в таких системах разреженные массивы. Но, когда вы получаете доступ к каждой странице, ЦП генерирует прерывание, и ОС должна находить физическую память для поддержки этой страницы (подкачка на не-RAM подкачки диска / файлов и т. Д., Если они настроены) — когда все опции исчерпаны (или иногда, когда ваш ОС опасно близка к пределу, и некоторые защитные процессы решают, что лучше убить некоторые процессы, чем позволить сбоям известных критических процессов), вы можете получить ошибку, как вы заметили. В конечном счете, нет никакого контроля над этим на уровне C ++. Вы можете быстро зарезервировать и записать все страницы, чтобы, скорее всего, вы потерпели неудачу перед выполнением всей обработки, но даже в этом случае вы можете оказаться в отчаянно нехватке памяти.


Отдельно вы можете разместить в памяти гораздо больше кругов, если сохраните их по значению. Тем не менее, вы не можете, если sizeof(Circle) > sizeof(Circle*) и фрагментация ограничивает вас, в этом случае вы можете попробовать std::deque, Тем не мение:

try
{
std::vector<Circle> array;
array.reserve(80000000);
for (long long i = 0; i < 80000000; i++) {
array.emplace_back(1, i);
}
catch (const bad_alloc& ba)
{
std::cerr << "Memory Exhaustion\n";
}
2

Другие решения

Контролируйте свою память процесса через диспетчер задач — вы можете использовать всю память, отведенную для процесса (в ожидании начальной точки и размера Circle).

если вы работаете на компьютере с Win32, то для этой операции у вас есть ~ 2 ГБ пространства памяти процесса

1

Во-первых, как вы уверены, что выдается единственно возможное исключение? std::bad_alloc? Я очень рекомендую добавить catch (...) блок после вашего catch (const bad_alloc&) заблокировать просто чтобы убедиться что ты прав. Конечно, с catch (...) Вы не будете знать, что было поймано, только то, что это не было bad_alloc,

Во-вторых, если вы как-то запускаете неопределенное поведение (скажем, разыменовывая NULL указатель), вы не обязательно получите исключение; вы не обязательно получите какое-либо поведение, которое имеет смысл в соответствии с правилами языка.

В-третьих, как уже предлагалось в Linux вы можете вызывать убийцу нехватки памяти. Это не совсем совместимое со стандартами поведение, но это поведение, с которым вы можете столкнуться в реальной жизни.

0