[project @ 2004-09-27 09:04:15 by ross]
authorross <unknown>
Mon, 27 Sep 2004 09:04:17 +0000 (09:04 +0000)
committerross <unknown>
Mon, 27 Sep 2004 09:04:17 +0000 (09:04 +0000)
update documentation of memory allocation

Foreign/C/String.hs
Foreign/Marshal/Alloc.hs
Foreign/Marshal/Array.hs
Foreign/Marshal/Utils.hs

index c624588..b03d32b 100644 (file)
@@ -139,7 +139,9 @@ peekCStringLen = peekCAStringLen
 --
 -- * 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
@@ -147,7 +149,9 @@ 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
@@ -157,7 +161,9 @@ 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
@@ -167,7 +173,9 @@ 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
@@ -237,7 +245,9 @@ peekCAStringLen (cp, len)
 --
 -- * 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__
@@ -255,7 +265,9 @@ newCAString str = do
 -- | 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__
@@ -279,7 +291,9 @@ newCAStringLen 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.
 --
 withCAString :: String -> (CString -> IO a) -> IO a
 #ifndef __GLASGOW_HASKELL__
@@ -300,7 +314,9 @@ withCAString str f =
 --
 -- * 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__
@@ -376,7 +392,9 @@ peekCWStringLen (cp, len)  = do
 --
 -- * 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
@@ -384,7 +402,9 @@ 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
@@ -396,7 +416,9 @@ 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
@@ -406,7 +428,9 @@ 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
index fb9f8dd..dbd3644 100644 (file)
 -----------------------------------------------------------------------------
 
 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)
 
@@ -56,9 +58,12 @@ import Hugs.ForeignPtr               ( FinalizerPtr )
 -- 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
@@ -66,16 +71,22 @@ 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
@@ -83,11 +94,13 @@ 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
@@ -105,8 +118,15 @@ 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
@@ -117,16 +137,27 @@ 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
@@ -156,6 +187,7 @@ foreign import ccall unsafe "stdlib.h malloc"  _malloc  ::          CSize -> IO
 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
index 0799aa7..a28ccc8 100644 (file)
@@ -79,7 +79,8 @@ import GHC.Base
 -- 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
@@ -87,14 +88,14 @@ 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
@@ -102,7 +103,8 @@ 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)
@@ -115,7 +117,7 @@ reallocArray  = doRealloc undefined
     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)
@@ -174,6 +176,7 @@ pokeArray0 marker ptr vals = go vals 0#
 
 -- |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
@@ -191,6 +194,7 @@ newArray0 marker 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
index 8f11e56..91ae945 100644 (file)
@@ -70,7 +70,13 @@ import Foreign.C.Types               ( CInt(..) )
 -- 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  = 
@@ -79,9 +85,12 @@ 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  =
@@ -123,8 +132,8 @@ maybeNew :: (      a -> IO (Ptr a))
         -> (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)