1

I'm trying to figure out when the memory is allocated for my program. Here is my code

#include <unistd.h>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
  cout << "when the memory is allocated?";
  cout << endl;
  cout.flush();
  int * p = new int[250000000];
  sleep(3);
  cout << "address: " << p;
  cout << endl;
  cout.flush();
  sleep(3);
  cout << "value" << p[0];
  cout << endl;
  cout.flush();
  sleep(10);
  cout << "ending";
  cout << endl;
  return 0;
}

enter image description here

I kept track of it with Activity Monitor on my mac.

I found I didn't get the GB memory I applied. When the memory will be actually allocated for new int[250000000] in C++?

PutBere
  • 131
  • 1
  • 12
  • Unrelated: `cout << endl; cout.flush();` is utterly pointless. `endl` flushes already - and you don't even need that. Use `cout << '\n';` instead. – Ted Lyngmo Jan 22 '21 at 23:54
  • Unrelated2: You leak memory. Use `auto p = std::make_unique(250000000);` instead or even better: `std::vector p(250000000);` – Ted Lyngmo Jan 23 '21 at 00:05
  • Does this answer your question? [new\[\] doesn't decrease available memory until populated](https://stackoverflow.com/questions/5341395/new-doesnt-decrease-available-memory-until-populated) – JaMiT Jan 23 '21 at 00:08

1 Answers1

8

OSX is like other Unix operating systems and there is a difference between virtual memory and actually used memory. In the console program top these are called VIRT and RES (for resident).

When you allocate a big block like that, the program calls the operating system to reserve virtual memory space. That memory will only be actually used when your program writes to it. Not when it reads from it, because the virtual pages will all be mapped to zero to start with.

So, to see memory actually used, write a loop to set each array entry to some number.

Here is a C++17 update version of your program (if you read this before read it again for some reason my paste buffer had the old version in it):

#include <chrono>
#include <iostream>
#include <thread>

using namespace std;
using namespace std::literals;

int main() {
  cout << "when the memory is allocated?";
  cout << endl;
  constexpr size_t p_count = 250000000;
  int *p = new int[p_count];
  this_thread::sleep_for(3s);
  cout << "address: " << p;
  cout << endl;
  this_thread::sleep_for(3s);
  cout << "value: " << p[0];
  cout << endl;
  for (size_t i = 0; i < p_count; ++i) {
    p[i] = i;
  }
  this_thread::sleep_for(10s);
  cout << "ending";
  cout << endl;
  return 0;
}
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • Does that depends on system then? Also, does accessing the array (reading it) converts it to "actual" memory? – yaozhang Jan 22 '21 at 23:58
  • @gamusren Yes it depends on the system. A system isn't required to have virtual memory. Isn't your second question answered above? Instead of `cout << "value" << p[0];` you could do `std::iota(p, p + 250000000, 1);` to fill the allocated memory with data. – Ted Lyngmo Jan 22 '21 at 23:59
  • @gamusren Reading the memory does not convert it to "real" memory. When the virtual map is created each memory block is mapped to the same block of zero memory. The operating system keeps one just for this. So if the OS uses 4K blocks `p[0]` and `p[4096]` read from the same physical RAM and that RAM is set to zero. – Zan Lynx Jan 23 '21 at 00:11