How to detect stack overflow?

Hi there,

Recently I tried running my C++ program with a much larger data set, and I quickly got an error crashing the program. I was quite surprised, as this program has worked fine up until now. Looking further into this, I have come to the conclusion that this error might be due to stack overflow.

I have quite a lot of statements like this in the code, meaning array that are not declared at compile time but rather at run time:

double cov[ind];

As far as I know (please correct me if I am wrong) these are put on the stack. And if the length of them become very long, it might cause stack overflow.

So I know I need to start replacing these with std::vector. However my question is there a sure way to sort of diagnose that this is indeed stack overflow causing the issue? Instead of basing it on my inferences.
When the program crashes, it probably gives some indication of the problem. If you're lucky, it will say that the stack overflowed. Otherwise it might say that it had an illegal memory access and it will give the address. You might be able to tell if that's a stack address by printing the addresses of a few stack variables to see where the stack is in the address space.

You could determine how to tell the compilation system to allocate more space to the stack. If you allocate more and the problem goes away, that's a pretty good indication that the stack was the problem.

But really, it's better to just replace
double cov[ind];
with
vector<double> cov(ind);
Variable length arrays are not standard C++, so your code might not compile on a different compiler. Thus it's best to just fix the problem.
You can get how much stack you have and the current stack pointer and see what % full it is in assembly languages. I do not know of a way to get these things in pure c++, though. It should be relatively simple to do this if you want to do it for debugging / analysis.
C++ by itself doesn't know what a stack is, so sadly there's no standard way to detect stack overflow.

What OS/environment are you working with? There are some system-specific mitigation possibilities.
Last edited on
run through a debugger
debugger works great at a high/zen kind of level, but it will not be exact if you are on the redline. because debug stack frames have extra junk, for the debugging purposes.
Yeah, I'm with @dhayden on this.

I was confused when you said,

I have quite a lot of statements like this in the code, meaning array that are not declared at compile time but rather at run time:

double cov[ind];


double cov[ind]; shouldn't compile unless ind is defined at compile time to some constant integer type.

If you're attempting to define a dynamic array at run-time with standard C++, you're better off using:

1
2
 double* cov;
cov = new double[runtimeValue];


Of course that allocates on the heap, which is generally where you want to allocate runtime memory anyway.

As @dhayden said, you're better off using a std::vector. They're most likely implemented as a dynamic array underneath and expose a user-friendly API to work with, plus, they clean themselves up automatically when they're out of scope*


*Unless you have an std::vector<myPointer*>. Then the pointers themselves will be cleaned up, but the memory to which they point will not. For that, You'd need:

std::vector<std::unique_ptr<myPointer>>;

EDIT: But to actually answer your question, if you go with one of these other approaches:

`operator new` actually throws `bad_alloc` if it's not able to get the resources you need, which would be a major indicator if you're using too much of your system's memory.
Last edited on
if it helps the vector version of
double cov[ind];
is
vector<double> cov(ind);
and the code should compile and execute fine as-is (if it was working before).
if you are going out of bounds or something else, it won't help at all. If it was stack blowout, it will help.
Topic archived. No new replies allowed.