Let's say I have 8 Gigabytes of RAM and 16 Gigabytes of swap memory. Can I allocate a 20 Gigabyte array there in C? If yes, how is it possible? What would that memory layout look like?
-
Sure, if your OS allows it. Not really a C or C++ question. Try it and see. You will need a 64 bit sys. As for how it "looks", it looks just like a large array. But when you access different elements it will slow down at times. Especially when it has to swap. – doug Mar 18 '22 at 21:02
-
Virtual Memory and Swap Space are like totally under the control of the operating system and have nothing to do with the C or C++ languages. The request starts with a call to the OS to allocate memory ... – Thomas Matthews Mar 18 '22 at 21:02
-
2You can. The 20GB is broken into pages, usually either 4KB or 1MB each on current hardware, and are swapped in (and out) as needed by the operating system in response to page faults based on the address being accessed. – 500 - Internal Server Error Mar 18 '22 at 21:03
-
try it, its like a 10 line c program – pm100 Mar 18 '22 at 21:17
3 Answers
[linux] Can I create an array exceeding RAM, if I have enough swap memory?
Yes, you can. Note that accessing swap is veerry slooww.
how is it possible
Allocate dynamic memory. The operating system handles the rest.
How would that memory layout look like?
On an amd64 system, you can have 256 TiB of address space. You can easily fit a contiguous block of 8 GiB in that space. The operating system divides the virtual memory into pages and copies the pages between physical memory and swap space as needed.

- 232,697
- 12
- 197
- 326
-
Thanks for the answer, but if I try it, I get a segmentation fault as soon as I write to the memory. I tried it both with malloc and C++ new. – Finn Mar 19 '22 at 08:39
-
1@Finn how much memory are you trying to allocate? How much memory and swap space do you have available? – Alan Birtles Mar 19 '22 at 15:31
-
Modern operating systems use virtual memory. In Linux and most other OSes rach process has it's own address space according to the abilities of the architecture. You can check the size of the virtual address space in /proc/cpuinfo
. For example you may see:
address sizes : 43 bits physical, 48 bits virtual
This means that virtual addresses use 48 bit. Half of that is reserved for the kernel so you only can use 47 bit, or 128TiB. Any memory you allocate will be placed somewhere in those 128 TiB of address space as if you actually had that much memory.
Linux uses demand page loading and per default over commits memory. When you say
char *mem = (char*)malloc(1'000'000'000'000);
what happens is that Linux picks a suitable address and just records that you have allocated 1'000'000'000'000 (rounded up to the nearest page) of memory starting at that point. (It does some sanity check that the amount isn't totally bonkers depending on the amount of physical memory that is free, the amount of swap that is free and the overcommit setting. Per default you can allocate a lot more than you have memory and swap.)
Note that at this point no physical memory and no swap space is connected to your allocated block at all. This changes when you first write to the memory:
mem[4096] = 0;
At this point the program will page fault. Linux checks the address is actually something your program is allowed to write to, finds a physical page and map it to &mem[4096]
. Then it lets the program retry to write there and everything continues.
If Linux can't find a physical page it will try to swap something out to make a physical page available for your programm. If that also fails your program will receive a SIGSEGV and likely die.
As a result you can allocate basically unlimited amounts of memory as long as you never write to more than the physical memory and swap and support. On the other hand if you initialize the memory (explicitly or implicitly using calloc()
) the system will quickly notice if you try to use more than available.

- 11,875
- 2
- 24
- 42
You can, but not with a simple malloc
. It's platform-dependent.
It requires an OS call to allocate swapable memory (it's VirtualAlloc
on Windows, for example, on Linux it should be mmap
and related functions).
Once it's done, the allocated memory is divided into pages, contiguous blocks of fixed size. You can lock a page, therefore it will be loaded in RAM and you can read and modify it freely. For old dinosaurs like me, it's exactly how EMS memory worked under DOS... You address your swappable memory with a kind of segment:offset
method: first, you divide your linear address by the page size to find which page is needed, then you use the remainder to get the offset within this page.
Once unlocked, the page remains in memory until the OS needs memory: then, an unlocked page will be flushed to disk, in swap, and discarded in RAM... Until you lock (and load...) it again, but this operation may requires to free RAM, therefore another process may have its unlocked pages swapped BEFORE your own page is loaded again. And this is damnly SLOOOOOOW... Even on a SSD!
So, it's not always a good thing to use swap. A better way is to use memory mapped files - perfect for reading very big files mostly sequentially, with few random accesses - if it can suits your needs.

- 1,483
- 4
- 13
-
2
-
@AlanBirtles Because `malloc` returns a **contiguous** memory area, on the heap. Heap size is limited for every process, and isn't usually swapable - some OS/C compilers _MAY_ allow it as a specificity, but it is NOT portable nor guaranteed. You can allocate memory by "tiny" blocks (i.e. 1 MB) until memory is full, free one block every two, try to allocate a big block of the freed size: it should fail because heap will be fragmented - so no more CONTIGUOUS memory left... The whole process' heap may be swapped when a whole process is suspended in background, but not individual blocks inside. – Wisblade Mar 19 '22 at 03:22
-
1That should probably be in your answer (though it sounds more like "might not always be able to" rather than "can't") – Alan Birtles Mar 19 '22 at 06:47
-
@AlanBirtles I disagree. The C norm says that it's not the case - exceptions aren't rule... You can't use extensions provided by either a compiler or an OS as something reliable. You must understand that a HUGE part of C/C++ code isn't on desktop computers, but on embedded machines... And even on desktop, it concerns not more than few percents of the whole desktop machines. So it's irrelevant to assume that a platform-dependent **non-standard** extension worth to be even mentionned. Windows/MSVC also have a lot of non-standard features, but only Windows specialists use (and know) them. – Wisblade Mar 19 '22 at 12:42
-
1(1) `malloc` returns contiguous virtual memory. Generally, operating systems are perfectly capable of swapping this memory to disk. That is a major purpose of having virtual memory. (2) The dynamically allocated memory provided by `malloc` (proper terminology; “heap” is sloppy slang) is usually swappable. (3) C compilers generally have little or no involvement in whether the memory provided by `malloc` is swappable; this is beyond their jursidiction. (4) Individual pages of the memory are swappable; there is no constraint that all or none of the memory must be swapped. This answer is bunk. – Eric Postpischil Mar 19 '22 at 12:50
-
1Your answer isn't talking about embedded platforms though, it talks about Windows and Linux which are virtual memory systems and their heap memory is paged and malloc can allocate large sizes. There might be more efficient calls but malloc is quite capable of doing it – Alan Birtles Mar 19 '22 at 13:29
-
@EricPostpischil Even the latest [C18 standard](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf) (§7.22.3.4) don't say **ANYTHING** about allocated memory nature, therefore you can't assume a PORTABLE, always true, answer. Virtual? Near mandatory on multitasked OS, near never the case on 8/16 bits machines. Paged? Nothing. Swappable? Nothing said about that either. The norm itself don't even contains the word "swap" or "virtual"... So it's platform-dependent, and it's not a question about C itself. – Wisblade Mar 19 '22 at 14:56
-
@AlanBirtles Just tested, for peace of mind: Windows 10, MSVC 2019, x64 mode. A call to `malloc(20*1024*1024*1024)` is flagged by the compiler as _"overflow in expression; result is '0' with type 'int'"_. Fun fact, it's for Unix compatibility reason, it seems... – Wisblade Mar 19 '22 at 14:57
-
1The argument to `malloc` is `size_t` though not `int`, I imagine the warning will disappear with the appropriate literal suffixes – Alan Birtles Mar 19 '22 at 15:29
-
1Just tested `malloc(20ULL * 1024ULL * 1024ULL * 1024ULL)` in visual studio on a machine with 14GB of free memory, after a bit of swap thrashing the `malloc` call succeeds with no compiler warnings. – Alan Birtles Mar 19 '22 at 16:13
-
I am interested in an answer for desktop computers, it is ok if it is not portable to embedded systems. Nevertheless, thanks for the differentiation. But if I try to allocate 25GB of memory on a desktop machine (Manjaro i3 x86-64) with 16GB RAM and 32GB swap, I get a segfault. – Finn Mar 21 '22 at 10:43
-
@Finn As I said, it doesn't surprise me a lot. I had to deal with huge data before (>100 GB): the _ONLY_ decent way I found to deal with them (Windows) was to use `VirtualAlloc` (and manage manually paging/swap) and `MapViewOfFile` for the final dump - and BTW, perfs were simply stunning compared to "automatic" swap handling... On Linux, it's `mmap` and/or have a kernel with `overcommit` enabled (reason why it's not portable). In C++, you can even define your own allocator to handle such situations and let it be (quite) behind the scene, while still having a fine control over paging/swapping. – Wisblade Mar 21 '22 at 11:01