LINUX.ORG.RU

Небольшой вопрос про память

 


0

1

Всем привет. Есть вопрос касательно допустимых выделений памяти с помощью операции new.

Провел небольшой тэст:

До открытия окна создал следующий массив

int* LargeMassive; LargeMassive=new int[262144000000]; LargeMassive[262143999999]=115;

Программа запустилась и окно открылось безо всяких ошибок. Однако при этом утилита системный монитор показывает, что занимаемая приложением память не получила заметных увеличений, а то и вовсе никаких (или там только статически выделенная память отображается?).Раздел подкачки тоже без изменений. При этом std::cout << LargeMassive[262143999999];Честно выдает 115. Предыдущий элемент дает 0.

Но как так? Если я посчитал правильно, такой массив должен забрать 976 GB (sic!) из кучи.

А вот если я допишу еще нолик к размеру массива, наконец вижу ошибку bad_alloc. Но все равно, как операционка заставляет существовать тот массив?

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

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

А как можно безопасно выделять память, точно зная, что ты ее получил?Или можно положить, что если ее требуемое количество не больше оставшейся физической+оставшаяся подкачка+- какая-то небольшая величина, то все будет ок?)

Nerevarino
() автор топика
Ответ на: комментарий от hateyoufeel
~/dev> cat alloc.cc 
int main()
{
    int* LargeArray = new int[262144000000];
    LargeArray[262143999999] = 115;

    return 0;
}
~/dev> clang++ alloc.cc -o alloc
~/dev> ./alloc                  
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
zsh: abort      ./alloc
~/dev> sudo sysctl vm/overcommit_memory 
vm.overcommit_memory = 0
~/dev> sudo sysctl vm/overcommit_memory=1
vm.overcommit_memory = 1
~/dev> ./alloc                           
~/dev> 

Q.E.D.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от Nerevarino

А я на 32 бит ноуте

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

у тебя же там целочисленное переполнение небось — в индексе массива?

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

262144000000×4/1024/1024/1024 вот так 976 и вышло. На индекс 262144000000 комп не ругался, честно. Впрочем, так ли это важно)

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

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

mmap(..., MAP_POPULATE);

Может послать segfault или sigbus.

mv ★★★★★
()
Ответ на: комментарий от FIL

Такие большие не нужны, но рано или поздно столкнусь с «краевыми моментами памяти». Вот и интересно, что происходит. Простой пример: взять какой - нибудь простой растровый редактор. Понятное дело, что прога рассчитана на работу с изображениями размера....нуу не больше 4К ,я думаю. А что будет, если в нее грузануть отсканутое изображение ватмана А0 в каком-нибудь 1200 dpi разрешении. Тут нужна защита, ведь упавшее приложение - дурной тон...или не всегда?

Nerevarino
() автор топика
Ответ на: комментарий от FIL

А краевые моменты будут везде, где объем данных заранее неизвестен. Можно конечно принять допущения....но хотелось бы знать реальные способы защиты.

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

Так пока в голову приходит только, что при огромном объеме данных, надо загружать их фрагмент и с ним работать, потом его выгружать и загружать другой. Или данные на лету как-то сжимать-разжимать.

Nerevarino
() автор топика

операнда, операция

если мне память не изм. даже на жабе жеэс этим нью ничегошеньки не прибавляется. Кажется это настройки контейнера оставляют (без 0) значение, (?).

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

Впрочем, так ли это важно)

Ага, неважно, было переполнение индекса или нет, типа.

std::cout << &LargeMassive[262143999999] - LargeMassive << "\n";
150994943, а не ваши 100500.

Sorcerer ★★★★★
()
Ответ на: комментарий от Nerevarino

но хотелось бы знать реальные способы защиты.

какие-ещё реальные способы защиты?

представь что ты *гарантированно* получило нужный объям памяти для своей программы.

теперь твоя программу будет работать... хм... велликолепно!.. хм.. точно ли?

ответ: очевидно нет! :)

как только в операционной системе будет нехватать памяти (по вине и *других* программ тоже) — OOM_Killer начнёт свои убийства...

....а теперь не хочешь ли ты ещё и изобрести способ который бы попросил бы OOM_Killer не убивать *именно_твою* программу? :-)

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

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

а всякие программисты-ламерюги — будут оставлять это значение поумолчанию (и даже не будут использовать suid-бит\CAP_SYS_RESOURCE на исполняемом файле, для получения привелегий относительной этой махинации)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 2)
Ответ на: комментарий от user_id_68054

только полный дебил будет ставить suid-бит\CAP_SYS_RESOURCE на каждую программу. админ должен задать повышенный приоритет важной программе

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

только полный дебил будет ставить suid-бит\CAP_SYS_RESOURCE на каждую программу. админ должен задать повышенный приоритет важной программе

если без сарказма — то совершенно верно. :)

и именно тоже самое — я считаю — относится и к ситуации когда какой-то программист хочет чтобы его программа ганатрированно получала бы свой большой кусок памяти.

сфигали это — какие-то одни (ЭЛИТАРНЫЕ) программы будут получать *гарантированно* свои куски памяти, а какие-то другие (ПРОСТАЧКОВЫЕ) программы видите ли должны надеяться на то что overcommit сработает с определённой вероятностью в их пользу :-) ..

ды блин! все программы должны быть в равных условиях! по крайней мере до тех пор пока пользователь компьютера (пользователь! а не программист) не захочет выделить ту или иную программу..

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

Сказать-то в целом что хотел?Что при нужде в большом количестве ОП, программа вполне себе может упасть и насрать на это? Конечно, программа не должна быть мажором среди остальных прог. Но я ведь именно про ЛЮБЫЕ действия пользователя и привел пример. Пользователь загрузил картинку over9000×over9000 пикселей.Программа что должна сделать? Упасть? Попробовать отобрать память?Сказать пользователю что он козел?

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

Последнее и это хороший тон

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