Alexander Malakhov
Alexander Malakhov

Reputation: 3529

Why memory allocation of 2^80 bytes doesn't fail?

Following code doesn't throw exception and prints "success". Why ?

#include <iostream>

int main() 
{
    size_t size = size_t(1024)*1024*1024*1024*1024*1024*1024*1024;
    char* data = new char[size];

    if (data == NULL)
        std::cout << "fail" << std::endl;
    else
        std::cout << "success" << std::endl;

    return 0;
}

And if this is how it's meant to work, how do I check that I have enough memory ?

[Edit: made my stupid code a bit more correct, now it would at least fail on x64 if I remove two *1024]

Upvotes: 16

Views: 1315

Answers (5)

Remus Rusanu
Remus Rusanu

Reputation: 294287

Be aware that on linux malloc (which ultimately backs new) can overcommit:

Since 2.1.27 there are a sysctl VM_OVERCOMMIT_MEMORY and proc file /proc/sys/vm/overcommit_memory with values 1: do overcommit, and 0 (default): don't.

malloc will succeed and reserve the VA but not back it up with pages. When a page is accessed it may or may not succeed to committ it. OOM Killer may run. IF all fails, you'll get an GPF on access.

Opinions are divided whether this behavior is crazy (sane people are on this camp) or brilliant (crazy people are on that camp).

Upvotes: 4

user529758
user529758

Reputation:

1024*1024*1024*1024*1024*1024*1024*1024

causes an integer overflow when calculated - that is, it will be taken modulo 2^32 (or 2^64, depending on your system), and that's zero bytes which can be allocated.

Upvotes: 5

Artie
Artie

Reputation: 503

Perhaps you are aware of the following, but I will state it just for clarification. An exception is not being literally thrown, the code is being tested by if statements. Regardless of what terminology and methods you are using for your test, there is a more relevant observation to take note on. Your system holds a maximum value for integers, and C++ will take it into consideration during compilation by doing checks and behaving some way accordingly. Once again, you may also already know that. My guess would be that the value either went back to 0 then up to the excessive amount or that the value that was there before the pointer started pointing to it was kept intact (Most likely). In that case, the pointer wouldn't be NULL. Try giving making it NULL upon declaration, then allocate the memory and see weather or not it passes your if statements.

Upvotes: 1

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234474

My compiler can answer this one:

$ g++ --version
g++ (GCC) 4.7.1 20120721 (prerelease)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -Wall -Wextra -pedantic q12507456.c++
q12507456.c++: In function 'int main()':
q12507456.c++:5:42: warning: integer overflow in expression [-Woverflow]
$

Upvotes: 20

mathematician1975
mathematician1975

Reputation: 21351

This is more than likely to be the fact that the number you are requesting is too large to be stored within an integer and you are experiencing overflow here and the memory allocated is in fact far far less than you think it is.

Here 2^80 = 1208925819614629174706176 according to http://en.wikipedia.org/wiki/Yobibyte

Upvotes: 6

Related Questions