Good day. When transferring a Linux application to the win32 (mingw32) platform, there was a problem of reserving memory when creating an array of the maximum allowable size. If the Linux code works without problems:

int V_V = std::numeric_limits<int>::max(); std::unique_ptr<short[]> space{new short[V_V]}; 

then an exception is generated in win32. I tried to programmatically find the maximum allowable value for this platform:

 try { std::unique_ptr<short[]> space{new short[V_V]}; if (found = step_setup()) cout << V_V << ": array created on " << &space[0] << endl; } catch(std::exception & e) { show_err(e); V_V -= step; } 

and suddenly found out that the permissible limit values ​​for creating an array are not constant:

 f:\cDev\test_limit.exe 2147483647: std::bad_array_new_length 1047483647: std::bad_alloc 829153681: array created on 0x1dc2020 f:\cDev\test_limit.exe 2147483647: std::bad_array_new_length 1047483647: std::bad_alloc 828911645: array created on 0x1e30020 

And they can change in 7m (!) Level: from 828911645 to 829153681.

Is there a software API in the standard library (without "windows.h") to get the size limit value for the array being created?

Here is the complete test code:

 #include <iostream> #include <memory> #include <limits> using std::cout; using std::endl; int V_V = std::numeric_limits<int>::max(); // creating array size int step = 100000000; // step for search bool step_setup() { if(step > 1) { V_V += step; step = step / 10; return false; } else { return true; } } // Display only first error message void show_err(std::exception & e) { static std::string err{}; if(err != e.what()) { err = e.what(); cout << V_V << ": " << err << endl; } return; } int main() { cout << endl; bool found = false; while (!found) { try { std::unique_ptr<short[]> space{new short[V_V]}; if (found = step_setup()) cout << V_V << ": array created on " << &space[0] << endl; } catch(std::exception & e) { show_err(e); V_V -= step; } } return EXIT_SUCCESS; } 
  • MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); GlobalMemoryStatusEx(&statex); ullAvailPageFile - max array size, if not backup, ullAvailVirtual . Can I get the full code, do not understand something, it shows the address of the highlighted byte?) - J. Doe
  • added full code at the end of the message. - bigov
  • Have you tried Linux with all this memory? Write something to each byte? Since giving the link as an answer is not considered comme il faut, I will give a comment: read task 23 of Sutter’s “New Challenges in C ++”, there is on this topic. As I understand the situation, the operating system commands here, which itself determines which resources are available to you at the moment . It is necessary to change the environment - something has worked in the background, the program is not running from the same physical address - and the differences begin. In the allocation of one piece of 4G of memory in Linux, too little is believed - or something you do not agree :) - Harry
  • @Harry checked it out, allocates 25 gig and writes =, I interrupted because it slows down, it would be necessary to check further). Here is the wrong finding, I would write my own only in the comments is unpredictable. In windows 8, the size = 3 * .ullTotalPhys - .ullTotalPageFile + .ullAvailPageFile , you can reserve more, but I don’t understand why I don’t use it - J. Doe
  • 2
    @ J.Doe 25G - no way to address 32 bits ... - Harry

1 answer 1

In the standard C ++ library there is no software API for directly determining the size of allocated memory. But you can slightly change the client code and use the standard container, which by the way is recommended in C ++. And then ask for the value of the size limit of the created container. For example:

 // comparing size, capacity and max_size #include <iostream> #include <vector> int main () { std::vector<int> myvector; // set some content in the vector: for (int i=0; i<100; i++) myvector.push_back(i); std::cout << "size: " << myvector.size() << "\n"; std::cout << "capacity: " << myvector.capacity() << "\n"; std::cout << "max_size: " << myvector.max_size() << "\n"; return 0; } 

The output of the program:

 size: 100 capacity: 128 max_size: 1073741823 
  • one
    max_size is simply the maximum theoretical container size. "1073741823 * 4 == 0xFFFFFFFC" - that is, without 4 bytes 4 gigabytes. I can guarantee that to allocate more than 2 gigs to 90% of 32 bit systems is very, very costly, not to mention 4. So your code absolutely does not solve the problem posed in the question. - KoVadim
  • I want to note that on the 32-bit system the result of "max_size" will be different - it will correspond to the capability of the testing system. And in the question it is required to “get the boundary value of the size”. So my answer solves the problem. - bigov
  • one
    The above result is just for a 32bit system (to be more precise, for a 32bit binary). And you won’t believe it, on all 32bit systems where I tried this code, it outputs the same thing. Moreover, if a 32-bit binary is run on a 64-bit system, the result will be the same. - KoVadim