Question

I am trying to save a vector full of pointer to Circle objects. Sometimes the bad_alloc catch works, but sometimes it doesn't, then I get the error message:

This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information."

Maybe the vector array can't allocate more memory... But the bad_alloc doesn't catch it.

Circle *ptr;
vector<Circle*> ptrarray;

try{
  for (long long i = 0; i < 80000000; i++) {
    ptr = new Circle(1,i);
    ptrarray.push_back(ptr);
  }
}catch(bad_alloc &ba){
  cout << "Memory Leak" << endl;
}

Would be great if someone could help me ;) Thanks in advance

Was it helpful?

Solution

Many Operating Systems will allow processes to request more virtual addresses (nominally available memory) than it has virtual memory to support, on the assumption that the processes may not actually access all the pages. Famously, this allows Sparse Arrays to be practical on such systems. But, as you access each page the CPU generates an interrupt and the OS must find physical memory to back that page (swapping out to non-RAM swap disk/files etc too if configured) - when all options are exhausted (or sometimes when your OS is dangerously close to the limit and some protective process decides it's better to kill some processes than let known critical ones start failing), you may get an error like you've observed. Ultimately, there's no control over this at the C++ level. You can reserve and write all pages quickly so you'll likely fail before doing all your processing, but even then you may be terminated in a desperately low-memory situation.


Separately, you may be able to fit a lot more circles in to memory if you store them by value. That said, you may not if sizeof(Circle) > sizeof(Circle*) and fragmentation is limiting you, in which case you might try a std::deque. Anyway:

try
{
    std::vector<Circle> array;
    array.reserve(80000000);
    for (long long i = 0; i < 80000000; i++) {
        array.emplace_back(1, i);
}
catch (const bad_alloc& ba)
{
    std::cerr << "Memory Exhaustion\n";
}

OTHER TIPS

Monitor your process memory via task manager - you might consume all memory allowed for the process (pending your starting point and the size of Circle).

if you are on a Win32 machine, then you have ~2GB of process memory space for this operation

First, how are you sure that the only possible exception thrown is std::bad_alloc? I would highly recommend adding a catch (...) block after your catch (const bad_alloc&) block just to verify that you're right. Of course, with catch (...) you won't know what was caught, only that it wasn't bad_alloc.

Second, if you somehow trigger undefined behavior (say, by dereferencing a NULL pointer), you won't necessarily get an exception; you won't necessarily get any behavior that makes sense according to the language rules.

Third, as already suggested on Linux you might be triggering the out of memory killer. It's not truly standards compliant behavior, but it's behavior you can run into in real life.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top