You've trashed your allocated memory pool.
Unfortunately, the code you've posted is probably OK (if you've been staring at it for that long without solving the problem).
The thing of it is, where the fault occurred (the real code you need to fix) is seldom the same as the code which notices there's a problem (the code you posted). It's this remoteness of "cause" and "effect" which really takes the time in solving these kinds of problems.
The fact that your code hasn't crashed up to now just makes you lucky, not good.
What you do about it now however is harder to say.
You could look at the MALLOC_DBG options, and cause it to call the pool-checking functions on every alloc/free call. This will slow it down, but it will notice the problem a lot sooner.