If you want background, see here. In short, the question is: “What's actual difference between bracket (mallocBytes n) free and allocaBytes from Foreign.Marshall.Alloc”.
Normally in C, alloca allocates on stack and malloc allocates on heap. I'm not sure what's going on with it in Haskell, but I would not expect a difference between the above-mentioned equations other than speed. If you clicked the background link though, you know that with compiled code bracket (mallocBytes n) free was resulting in “double free or corruption” while allocaBytes works fine (the problem is not visible when in GHCi at all, everything works fine in both cases).
By now I've spent two days in painful debugging and I'm pretty confident that bracket (mallocBytes n) free was unstable somehow and the rest of the code is reliable. I'd like to find out what's the deal with bracket (mallocBytes n) free.
bracket (mallocBytes size) freewill use C'smallocandfree, whereasallocaBytes sizewill use memory that's managed by GHCs garbage collection. That in itself is a huge difference already, since thePtrofallocaBytesmight be surrounded by unused (but allocated) memory:Result:
As you can see, although we've used
arr[-1] = 0,allocaByteshappily ignored that error. However,freewill (often) blow up in your face if you write to position-1. It will also blow up in your face if there has been a memory corruption on another allocated memory region*.Also, with
allocaBytes, it's likely that the pointer points somewhere into already allocated memory, not to the start of one, e.g.What does that mean? Well,
allocaBytesis less likely to blow up in your face, but at the cost that you don't notice if your C-code variant would lead to memory corruption. Even worse, as soon as you write outside of the bounds returned byallocaBytes, your possibly corrupting other Haskell values silently.However, we're talking here about undefined behaviour. The code above may or may not crash on your system. It may also crash in the
allocaBytespart.If I were you, I would trace the
mallocandfreecalls.* I once had a "double use of free" error in the middle of my program. Debugged everything, rewrote most of the "bad" routine. Unfortunately, the error vanished in debug builds, but recurred in release builds. It turned out that in the first ten lines of
main, I accidentally wrote tob[i - 1]withi = 0.