[Haskell-cafe] peekCString & free memory
elbarteau at gmail.com
Mon Nov 30 16:01:26 EST 2009
I used this advice:
to make 'xmlFree' callable from Haskell.
I was completly wrong in my first post...
I do apologize.
On Sun, Nov 29, 2009 at 8:56 PM, El Barto <elbarteau at gmail.com> wrote:
> Thanks for your help & time,
> I checked the C API documentation:
> "The result must be deallocated with xmlFree()"
> I pushed the sources here:
> My problem is with the function at line 249 in Text.XML.LibXML.XmlReader
> To make it work, I have to comment out the line where xmlFree is called.
> -- xmlChar * xmlTextReaderValue(xmlTextReaderPtr reader)
> -- Returns:the string or NULL if not available. The result must be
> deallocated with xmlFree()
> foreign import ccall unsafe "xmlreader.h xmlTextReaderValue"
> c_xmlTextReaderValue :: Ptr XmlTextReader -> IO (CString)
> value :: (MonadIO m) => XmlReader -> m (Maybe B.ByteString)
> value (XmlReader reader_fp) = liftIO $
> withForeignPtr reader_fp $ \reader_ptr -> do
> cstr <- c_xmlTextReaderValue reader_ptr
> fromPtr B.packCString cstr c_xmlFree
> fromPtr :: (Ptr a -> IO b) -> Ptr a -> (Ptr a -> IO ()) -> IO (Maybe b)
> fromPtr c2h ptr free | ptr == nullPtr = return Nothing
> | otherwise = do
> r <- c2h ptr
> free ptr -- FIXME
> return (Just r)
> May be the binding to xmlFree is wrong?
> foreign import ccall unsafe "xmlreader.h xmlFree"
> c_xmlFree :: Ptr a -> IO ()
> To test, you will need libxml2-dev:
> $ runhaskell Setup configure --extra-include-dirs=/usr/include/libxml2/
> $ runhaskell Setup build
> $ ./dist/build/Test/Test
> C functions are described here:
> And here:
> On Sun, Nov 29, 2009 at 7:02 PM, Duncan Coutts <
> duncan.coutts at googlemail.com> wrote:
>> On Sun, 2009-11-29 at 18:00 +0100, El Barto wrote:
>> > Hello,
>> > I get a segfault when I do
>> > str <- peekCString ptr
>> > free ptr
>> > return (Just str)
>> As Thomas says, you've not really given us enough info here.
>> I'll make some guesses and observations anyway :-)
>> > But not when I don't free the C pointer.
>> Are you sure the C code does not also free the memory? That would lead
>> to a double-free which can easily manifest as a segfault.
>> > I also get the same behaviour with ByteString.packCString...
>> That's pretty odd since packCString does not free the C string, it makes
>> a copy. I suppose it could possibly segfault if your C string was not
>> actually null terminated (as C strings must be).
>> There are also variants that do not copy, such as
>> unsafePackMallocCString. See the docs for a description.
>> > Could you please tell me if the memory is correctly freed by GHC when
>> > I don't do it myself?
>> > And how can I specify a custom free function (i.e. xmlFree function in
>> > libxml2)?
>> See the documentation for ForeignPtr.
>> > Maybe I should use a data type with two fields : the String/ByteString
>> > and the ForeignPtr to the CString?
>> Is your C String supposed to be freed using the C free() function, or is
>> it supposed to be freed using xmlFree() or something?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe