В программах на C (++) обычно (то есть, если мы не говорим о интерпретации кода вместо его компиляции + непосредственного выполнения), массивы являются непрерывными в виртуальном адресном пространстве (если, конечно, существует такой вещь на рассматриваемой платформе).
Там, если большой массив не может быть выделен непрерывно, даже если имеется достаточно свободной памяти, вы получите либо исключение std :: bad_alloc (в C ++), либо NULL (из malloc () -подобных функций в C / C ++ или оператор броска, новый в C ++).
Виртуальная память (и подкачка на / с диска) обычно не решает проблемы фрагментации виртуального адресного пространства, или, по крайней мере, не напрямую, ее назначение другое. Обычно он позволяет программам думать, что памяти достаточно, а на самом деле ее нет. Оперативная память эффективно расширяется за счет свободного дискового пространства за счет снижения производительности, поскольку ОС вынуждена обмениваться данными между оперативной памятью и диском, когда возникает нехватка памяти.
Ваш массив (по частям или целиком) может быть выгружен на диск операционной системой. Но это сделано прозрачным для вашей программы, потому что всякий раз, когда ей нужно получить доступ к чему-либо из массива, ОС будет загружать его обратно (опять же, по частям или в целом, как операционная система сочтет необходимым).
В системах без виртуальной памяти нет преобразования виртуальных адресов в физические, и ваша программа будет работать напрямую с физической памятью, следовательно, ей придется иметь дело с фрагментацией физической памяти, а также конкурировать с другими программами как за свободную память, так и за адресное пространство, что повышает вероятность сбоев выделения (системы с виртуальной памятью часто запускают программы в отдельных виртуальных адресных пространствах, и фрагментация в виртуальном адресном пространстве приложения A не влияет на работу приложения B).