Valgrind can't detect stack corruption. Fortunately, almost all stack-related problems are caused by buffer overflows. Carefully look at all local array variables. Try to find the code which is overrunning one of them.
Because of the way local variables are stored, local variables in higher frames will also be corrupted during a buffer overflow. This makes it possible to use a trick to detect where the overflow occurs:
Code:
int main()
{
int overflow = 0x55AACCFF;
/* Your code */
}
Then run your program in gdb. Before starting it, add a watchpoint on the overflow variable with the command: "watch overflow". Then let it run. Hopefully, when the overflow occurs, it will change the value of the overflow variable and your program will break. Then you should be able to see what happened.
The problem with allowing it to crash is that it crashes AFTER the corruption has happened, so you don't see it happening.