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) free
will use C'smalloc
andfree
, whereasallocaBytes size
will use memory that's managed by GHCs garbage collection. That in itself is a huge difference already, since thePtr
ofallocaBytes
might be surrounded by unused (but allocated) memory:Result:
As you can see, although we've used
arr[-1] = 0
,allocaBytes
happily ignored that error. However,free
will (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,
allocaBytes
is 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
allocaBytes
part.If I were you, I would trace the
malloc
andfree
calls.* 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
.