--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C string and must be
+-- explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCString :: String -> IO CString
newCString = newCAString
-- | Marshal a Haskell string into a C string (ie, character array) with
-- explicit length information.
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C string and must be
+-- explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCStringLen :: String -> IO CStringLen
newCStringLen = newCAStringLen
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCString :: String -> (CString -> IO a) -> IO a
withCString = withCAString
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCStringLen :: String -> (CStringLen -> IO a) -> IO a
withCStringLen = withCAStringLen
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C string and must be
+-- explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCAString :: String -> IO CString
#ifndef __GLASGOW_HASKELL__
-- | Marshal a Haskell string into a C string (ie, character array) with
-- explicit length information.
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C string and must be
+-- explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCAStringLen :: String -> IO CStringLen
#ifndef __GLASGOW_HASKELL__
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCAString :: String -> (CString -> IO a) -> IO a
#ifndef __GLASGOW_HASKELL__
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCAStringLen :: String -> (CStringLen -> IO a) -> IO a
#ifndef __GLASGOW_HASKELL__
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C wide string and must
+-- be explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCWString :: String -> IO CWString
newCWString = newArray0 wNUL . charsToCWchars
-- | Marshal a Haskell string into a C wide string (ie, wide character array)
-- with explicit length information.
--
--- * new storage is allocated for the C string and must be explicitly freed
+-- * new storage is allocated for the C wide string and must
+-- be explicitly freed using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree'.
--
newCWStringLen :: String -> IO CWStringLen
newCWStringLen str = do
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCWString :: String -> (CWString -> IO a) -> IO a
withCWString = withArray0 wNUL . charsToCWchars
--
-- * the Haskell string may /not/ contain any NUL characters
--
--- * see the lifetime constraints of 'Foreign.Marshal.Alloc.alloca'
+-- * the memory is freed when the subcomputation terminates (either
+-- normally or via an exception), so the pointer to the temporary
+-- storage must /not/ be used after this.
--
withCWStringLen :: String -> (CWStringLen -> IO a) -> IO a
withCWStringLen str act = withArray (charsToCWchars str) $ act . pairLength str
-----------------------------------------------------------------------------
module Foreign.Marshal.Alloc (
- -- * Allocation
- malloc, -- :: Storable a => IO (Ptr a)
- mallocBytes, -- :: Int -> IO (Ptr a)
-
+ -- * Memory allocation
+ -- ** Local allocation
alloca, -- :: Storable a => (Ptr a -> IO b) -> IO b
allocaBytes, -- :: Int -> (Ptr a -> IO b) -> IO b
+ -- ** Dynamic allocation
+ malloc, -- :: Storable a => IO (Ptr a)
+ mallocBytes, -- :: Int -> IO (Ptr a)
+
realloc, -- :: Storable b => Ptr a -> IO (Ptr b)
reallocBytes, -- :: Ptr a -> Int -> IO (Ptr a)
-- exported functions
-- ------------------
--- |Allocate space for storable type. The size of the area allocated
--- is determined by the 'sizeOf' method from the instance of
--- 'Storable' for the appropriate type.
+-- |Allocate a block of memory that is sufficient to hold values of type
+-- @a@. The size of the area allocated is determined by the 'sizeOf'
+-- method from the instance of 'Storable' for the appropriate type.
+--
+-- The memory may be deallocated using 'free' or 'finalizerFree' when
+-- no longer required.
--
malloc :: Storable a => IO (Ptr a)
malloc = doMalloc undefined
doMalloc :: Storable a => a -> IO (Ptr a)
doMalloc dummy = mallocBytes (sizeOf dummy)
--- |Allocate given number of bytes of storage, equivalent to C\'s @malloc()@.
+-- |Allocate a block of memory of the given number of bytes.
+-- The block of memory is sufficiently aligned for any of the basic
+-- foreign types that fits into a memory block of the allocated size.
+--
+-- The memory may be deallocated using 'free' or 'finalizerFree' when
+-- no longer required.
--
mallocBytes :: Int -> IO (Ptr a)
mallocBytes size = failWhenNULL "malloc" (_malloc (fromIntegral size))
--- |Temporarily allocate space for a storable type.
+-- |@'alloca' f@ executes the computation @f@, passing as argument
+-- a pointer to a temporarily allocated block of memory sufficient to
+-- hold values of type @a@.
--
--- * the pointer passed as an argument to the function must /not/ escape from
--- this function; in other words, in @alloca f@ the allocated storage must
--- not be used after @f@ returns
+-- The memory is freed when @f@ terminates (either normally or via an
+-- exception), so the pointer passed to @f@ must /not/ be used after this.
--
alloca :: Storable a => (Ptr a -> IO b) -> IO b
alloca = doAlloca undefined
doAlloca :: Storable a => a -> (Ptr a -> IO b) -> IO b
doAlloca dummy = allocaBytes (sizeOf dummy)
--- |Temporarily allocate the given number of bytes of storage.
+-- |@'allocaBytes' n f@ executes the computation @f@, passing as argument
+-- a pointer to a temporarily allocated block of memory of @n@ bytes.
+-- The block of memory is sufficiently aligned for any of the basic
+-- foreign types that fits into a memory block of the allocated size.
--
--- * the pointer passed as an argument to the function must /not/ escape from
--- this function; in other words, in @allocaBytes n f@ the allocated storage
--- must not be used after @f@ returns
+-- The memory is freed when @f@ terminates (either normally or via an
+-- exception), so the pointer passed to @f@ must /not/ be used after this.
--
#ifdef __GLASGOW_HASKELL__
allocaBytes :: Int -> (Ptr a -> IO b) -> IO b
allocaBytes size = bracket (mallocBytes size) free
#endif
--- |Adjust a malloc\'ed storage area to the given size of the required type
--- (corresponds to C\'s @realloc()@).
+-- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'
+-- to the size needed to store values of type @b@. The returned pointer
+-- may refer to an entirely different memory area, but will be suitably
+-- aligned to hold values of type @b@. The contents of the referenced
+-- memory area will be the same as of the original pointer up to the
+-- minimum of the original size and the size of values of type @b@.
+--
+-- If the argument to 'realloc' is 'nullPtr', 'realloc' behaves like
+-- 'malloc'.
--
realloc :: Storable b => Ptr a -> IO (Ptr b)
realloc = doRealloc undefined
in
failWhenNULL "realloc" (_realloc ptr size)
--- |Adjust a malloc\'ed storage area to the given size (equivalent to
--- C\'s @realloc()@).
+-- |Resize a memory area that was allocated with 'malloc' or 'mallocBytes'
+-- to the given size. The returned pointer may refer to an entirely
+-- different memory area, but will be sufficiently aligned for any of the
+-- basic foreign types that fits into a memory block of the given size.
+-- The contents of the referenced memory area will be the same as of
+-- the original pointer up to the minimum of the original size and the
+-- given size.
+--
+-- If the pointer argument to 'reallocBytes' is 'nullPtr', 'reallocBytes'
+-- behaves like 'malloc'. If the requested size is 0, 'reallocBytes'
+-- behaves like 'free'.
--
reallocBytes :: Ptr a -> Int -> IO (Ptr a)
reallocBytes ptr 0 = do free ptr; return nullPtr
reallocBytes ptr size =
failWhenNULL "realloc" (_realloc ptr (fromIntegral size))
--- |Free malloc\'ed storage (equivalent to
--- C\'s @free()@)
+-- |Free a block of memory that was allocated with 'malloc',
+-- 'mallocBytes', 'realloc', 'reallocBytes', 'Foreign.Marshal.Utils.new'
+-- or any of the @new@/X/ functions in "Foreign.Marshal.Array" or
+-- "Foreign.C.String".
--
free :: Ptr a -> IO ()
free = _free
foreign import ccall unsafe "stdlib.h realloc" _realloc :: Ptr a -> CSize -> IO (Ptr b)
foreign import ccall unsafe "stdlib.h free" _free :: Ptr a -> IO ()
--- | A pointer to a foreign function equivalent to 'free', which may be used
--- as a finalizer for storage allocated with 'malloc' or 'mallocBytes'.
+-- | A pointer to a foreign function equivalent to 'free', which may be
+-- used as a finalizer (cf 'Foreign.ForeignPtr.ForeignPtr') for storage
+-- allocated with 'malloc', 'mallocBytes', 'realloc' or 'reallocBytes'.
foreign import ccall unsafe "stdlib.h &free" finalizerFree :: FinalizerPtr a
-- allocation
-- ----------
--- |Allocate storage for the given number of elements of a storable type.
+-- |Allocate storage for the given number of elements of a storable type
+-- (like 'Foreign.Marshal.Alloc.malloc', but for multiple elements).
--
mallocArray :: Storable a => Int -> IO (Ptr a)
mallocArray = doMalloc undefined
doMalloc :: Storable a => a -> Int -> IO (Ptr a)
doMalloc dummy size = mallocBytes (size * sizeOf dummy)
--- |Like 'mallocArray', but add an extra element to signal the end of the array
+-- |Like 'mallocArray', but add an extra position to hold a special
+-- termination element.
--
mallocArray0 :: Storable a => Int -> IO (Ptr a)
mallocArray0 size = mallocArray (size + 1)
--- |Temporarily allocate space for the given number of elements.
---
--- * see 'Foreign.Marshal.Alloc.alloca' for the storage lifetime constraints
+-- |Temporarily allocate space for the given number of elements
+-- (like 'Foreign.Marshal.Alloc.alloca', but for multiple elements).
--
allocaArray :: Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray = doAlloca undefined
doAlloca :: Storable a => a -> Int -> (Ptr a -> IO b) -> IO b
doAlloca dummy size = allocaBytes (size * sizeOf dummy)
--- |Like 'allocaArray', but add an extra element to signal the end of the array
+-- |Like 'allocaArray', but add an extra position to hold a special
+-- termination element.
--
allocaArray0 :: Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray0 size = allocaArray (size + 1)
doRealloc :: Storable a => a -> Ptr a -> Int -> IO (Ptr a)
doRealloc dummy ptr size = reallocBytes ptr (size * sizeOf dummy)
--- |Adjust the size of an array while adding an element for the end marker
+-- |Adjust the size of an array including an extra position for the end marker.
--
reallocArray0 :: Storable a => Ptr a -> Int -> IO (Ptr a)
reallocArray0 ptr size = reallocArray ptr (size + 1)
-- |Write a list of storable elements into a newly allocated, consecutive
-- sequence of storable values
+-- (like 'Foreign.Marshal.Utils.new', but for multiple elements).
--
newArray :: Storable a => [a] -> IO (Ptr a)
newArray vals = do
return ptr
-- |Temporarily store a list of storable values in memory
+-- (like 'Foreign.Marshal.Utils.with', but for multiple elements).
--
withArray :: Storable a => [a] -> (Ptr a -> IO b) -> IO b
withArray vals = withArrayLen vals . const
-- combined allocation and marshalling
-- -----------------------------------
--- |Allocate storage for a value and marshal it into this storage
+-- |Allocate a block of memory and marshal a value into it
+-- (the combination of 'malloc' and 'poke').
+-- The size of the area allocated is determined by the 'Foreign.Storable.sizeOf'
+-- method from the instance of 'Storable' for the appropriate type.
+--
+-- The memory may be deallocated using 'Foreign.Marshal.Alloc.free' or
+-- 'Foreign.Marshal.Alloc.finalizerFree' when no longer required.
--
new :: Storable a => a -> IO (Ptr a)
new val =
poke ptr val
return ptr
--- |Allocate temporary storage for a value and marshal it into this storage
+-- |@'with' val f@ executes the computation @f@, passing as argument
+-- a pointer to a temporarily allocated block of memory into which
+-- 'val' has been marshalled (the combination of 'alloca' and 'poke').
--
--- * see the life time constraints imposed by 'alloca'
+-- The memory is freed when @f@ terminates (either normally or via an
+-- exception), so the pointer passed to @f@ must /not/ be used after this.
--
with :: Storable a => a -> (Ptr a -> IO b) -> IO b
with val f =
-> (Maybe a -> IO (Ptr a))
maybeNew = maybe (return nullPtr)
--- |Converts a @withXXX@ combinator into one marshalling a value wrapped into a
--- 'Maybe'
+-- |Converts a @withXXX@ combinator into one marshalling a value wrapped
+-- into a 'Maybe', using 'nullPtr' to represent 'Nothing'.
--
maybeWith :: ( a -> (Ptr b -> IO c) -> IO c)
-> (Maybe a -> (Ptr b -> IO c) -> IO c)