[Haskell-cafe] peekCString & free memory

El Barto elbarteau at gmail.com
Mon Nov 30 16:01:26 EST 2009


Ok,
I used this advice:
http://www.haskell.org/haskellwiki/GHC/Using_the_FFI#Importing_C_functions_that_turn_out_to_be_CPP_macros
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:
> http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderValue
> "The result must be deallocated with xmlFree()"
>
> I pushed the sources here:
> http://github.com/gwenn/libxml-reader
>
> 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:
> http://xmlsoft.org/html/libxml-xmlreader.html
> And here:
> http://xmlsoft.org/html/libxml-globals.html
>
> Regards.
>
>
> 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?
>>
>> Duncan
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20091130/da26e1d1/attachment.html


More information about the Haskell-Cafe mailing list