I am writing in C++ on a Windows machine in three environments:
- Docker Linux container with Ubuntu - g++ compiler (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
- WSL Ubuntu enviornment on Windows - g++ compiler (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
- Windows - gcc compiler (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
I am working with enormous datasets and basically need to be able to break them down into as-large-as-possible chunks to manipulate in memory. To find the size of blocks, I imagined something like the following:
size_t findOptimalSize(long long beginningSize) {
long long currentSize = beginningSize;
while (currentSize > 0) {
try {
std::vector<double> v(currentSize);
return currentSize;
} catch (std::bad_alloc &ex) {
currentSize /= 10;
}
}
return 0;
}
int main() {
long long size(50000000000000);
try {
std::vector<double> v(size);
std::cout << "success" << std::endl;
} catch (std::bad_alloc &ex){
std::cout << "badAlloc" << std::endl;
}
size_t optimal = findOptimalSize(size);
std::cout << "optimal size: " + std::to_string(optimal);
return 0;
}
The above code behaves perfectly as expected in the Windows environment. In the two Linux environments, however, while it is always able to throw the first bad_alloc exception, it then either does one of two things:
- Throws a SIGABRT with the following message:
new cannot satisfy memory request. This does not necessarily mean you have run out of virtual memory. It could be due to a stack violation caused by e.g. bad use of pointers or an out-of-date shared library
- After a few iterations, seems to fall into an endless loop at the line
std::vector<double> v(currentSize);(My best guess there is that it gets close to the amount of memory the Linux environment has available and it gets stuck waiting for that extra little bit of extra memory to be freed to satisfy my request)
Is there some way to accomplish what I'm attempting and sidestep these issues in the Linux environments? I'm guessing that the containers complicate matters and muddy up my simple allocation checks with their complex memory management logic.
How can I check whether I can allocate the memory in these circumstances?