4

I'm supposed to write a program that doesn't crash and can approximate the size of the free store (heap memory). And the hint is

Hint: Use a loop to allocate, say, 1000000 bytes at a time and add 1 to an unsigned long long counter; then when the allocation fails, print the counter times 1000000.0.

This is my first exposure to programming and c++ so I am totally lost on were to begin. Isn't the size of free store depend on the computer's ram? How could I possibly calculate the size of that large memory in bytes?

Also what is an unsigned long long?

trincot
  • 317,000
  • 35
  • 244
  • 286
Richard
  • 5,840
  • 36
  • 123
  • 208
  • 1
    Out of curiosity, who asked you to do this and why? – John Dibling Dec 02 '11 at 17:11
  • 3
    You can tell that allocation fails when `::operator new()` throws an exception. So... handle that exception! (Or use `std::malloc()` directly, which returns `NULL` on error.) – Kerrek SB Dec 02 '11 at 17:14
  • 2
    You shouldn't write over the question once it's been solved. That defeats the purpose of helping others in the future who might have had this same problem. Just accept an answer and leave the question as it was please. – Reid Mac Dec 02 '11 at 17:42
  • Do not remove your question after it has been answered! – lvella Dec 02 '11 at 17:43
  • The question is underspecified. There can be many definitions of memory, e.g. largest "new" allocatable block, number of allocatable blocks of predefined size, total physical memory, available address space, system heap, local heap, etc. And b.t.w. many systems won't commit memory pages on allocation until it's used, so testing innocuous, but some other do. – Gene Bushuyev Dec 02 '11 at 18:48

3 Answers3

5

Measuring RAM by successively allocating blocks until allocations fail is certainly one approach, but it is not how a professional programmer would solve the problem. It is tantamount to determining the size of a file by reading the whole thing in and counting the bytes one by one (one should use stat(), fstat(), or fseek() and ftell() instead).

A far better approach is to ask to operating system how much RAM is available. It, after all, definitely knows the answer to this.

On Linux you would use the sysinfo() API. Read this for an example.

On Windows you would use GetPhysicallyInstalledSystemMemory(). Read about it here.

On MacOS you would use the sysctl() API, with the CTL_HW and HW_MEMSIZE selectors.

This SO page has comprehensive examples for the three major platforms.

One more thing: on systems with virtual memory, the free store that you are trying to measure may be closer to the size of the system swap file on disk than the amount of physical RAM installed, and the state of other processes on the system will also affect the value measured by successive allocations.

Community
  • 1
  • 1
Randall Cook
  • 6,728
  • 6
  • 33
  • 68
  • I would just want to mention that the OS may think that the program is doing something important and try to kill another process in order to free up some memory (See → http://linux-mm.org/OOM_Killer). – Frank Oct 17 '13 at 02:16
1

A unsigned long long is a 64 bits intenger. It can represent any int inside the range [0,2^64].

Your program can't use all your RAM memory. THE OS limit the total amount of memory avaible to any program.

The source code:

char *heap;

unsigned long long heap_cont = 1;

while(1)
{
   //allocating the memory. Malloc returns a NULL pointer when fails.
   heap = (char *)malloc(sizeof(char)*heap_cont*1000000);
   if(heap == NULL)
   break;

   free(heap);
   heap_cont++;
}

std::cout << "Heap count: " << heap_cont * 1000000";
Ian Medeiros
  • 1,746
  • 9
  • 24
  • Can you explain why you are creating a pointer to a char? And what does sizeof(char) do? I tried this but with 1000000000, my system almost died, how long do you think it will take for 1000000? – Richard Dec 02 '11 at 17:34
  • I'm creating a pointer to a char because a char have a size of 1 byte. 10 chars will use 10 bytes of memory. sizeof(char) returns the size of a char. That's not needed because I know it's 1, but is good practice to check the size of the type you are malloc'ing. Yeah, probably your system will start to get very slow with this code running, probably your OS will start to get out of RAM and will start to use Phisycal Memory, wich is very slow. – Ian Medeiros Dec 02 '11 at 17:46
  • I don't mean to be critical to your solution, but this is mostly C, not C++. It is an answer on how to do it in C. –  Dec 02 '11 at 18:28
1

This is a good C++ question. The solution is simple, but it requires a decent understanding of loops, memory allocation, error checking, console output, and integer data types. Don't feel bad - if this is really your first exposure to programming it's crazy that someone expects you to answer this question.

The hint gives you everything you need. I'll break it down into steps, and you tell us which part is giving you trouble.

  • Use a loop
  • allocate, say, 1000000 bytes
  • add 1 to an unsigned long long counter
  • figure out when the allocation fails without crashing
  • print the counter times 1000000.0

Isn't the size of free store depend on the computer's ram?

Yes. It also depends on the other programs currently running on the machine.

How could I possibly calculate the size of that large memory in bytes?

The computer's must know the size of its own memory to operate correctly. Somewhere, the information exists or can be calculated.

what is an unsigned long long?

In C++11, it's guaranteed to be at least 64 bits. Before C++11, it's an unsigned integer data type that's at least as big as an unsigned long.

japreiss
  • 11,111
  • 2
  • 40
  • 77