Possible memory leak?
Chris Kuklewicz
haskell at list.mightyreason.com
Tue Jul 18 10:51:12 EDT 2006
I was working on pulling library calling code from JRegex into Text.Regex.Lazy
and I am wondering if this code for compiling regex.h regular expressions is a
potential memory leak:
> regcomp pattern flags = do
> regex_fptr <- mallocForeignPtrBytes (#const sizeof(regex_t))
> r <- withCString pattern $ \cstr ->
> withForeignPtr regex_fptr $ \p ->
> c_regcomp p cstr (fromIntegral flags)
> if (r == 0)
> then do addForeignPtrFinalizer ptr_regfree regex_fptr
> return (Regex regex_fptr)
> else error "Text.Regex.Posix.regcomp: error in pattern" -- ToDo
The (r/=0) path calls error, but never attaches the finalizer. And the man page
for regex says:
> The regfree() function frees any dynamically-allocated storage associated
> with the compiled RE pointed to by preg. The remaining regex_t is no
> longer a valid compiled RE and the effect of supplying it to regexec() or
> regerror() is undefined.
So it looks like the c_regcomp might allocate memory associated with regex_fptr
even in the event of an error, so this case needs the same finalizer.
I have not re-compiled GHC, but I have attached a small untested patch to change
the code to always trigger the finalizer when there is an error:
> regcomp pattern flags = do
> regex_fptr <- mallocForeignPtrBytes (#const sizeof(regex_t))
> addForeignPtrFinalizer ptr_regfree regex_fptr
> r <- withCString pattern $ \cstr ->
> withForeignPtr regex_fptr $ \p ->
> c_regcomp p cstr (fromIntegral flags)
> if (r == 0)
> then return (Regex regex_fptr)
> else do finalizeForeignPtr regex_fptr
> error "Text.Regex.Posix.regcomp: error in pattern" -- ToDo
Cheers,
Chris
-------------- next part --------------
--- Text/Regex/Posix-orig.hsc 2006-07-18 11:06:55.000000000 +0100
+++ Text/Regex/Posix.hsc 2006-07-18 11:18:57.000000000 +0100
@@ -79,13 +79,14 @@
-> IO Regex -- ^ Returns: the compiled regular expression
regcomp pattern flags = do
regex_fptr <- mallocForeignPtrBytes (#const sizeof(regex_t))
+ addForeignPtrFinalizer ptr_regfree regex_fptr
r <- withCString pattern $ \cstr ->
withForeignPtr regex_fptr $ \p ->
c_regcomp p cstr (fromIntegral flags)
if (r == 0)
- then do addForeignPtrFinalizer ptr_regfree regex_fptr
- return (Regex regex_fptr)
- else error "Text.Regex.Posix.regcomp: error in pattern" -- ToDo
+ then return (Regex regex_fptr)
+ else do finalizeForeignPtr regex_fptr
+ error "Text.Regex.Posix.regcomp: error in pattern" -- ToDo
-- -----------------------------------------------------------------------------
-- regexec
More information about the Glasgow-haskell-users
mailing list