Hi all, Suppose the next fragment main = newCString s1 >>= \p1 -> newCString s2 >>= \p2 -> let p3 = hstrL p2 p1 in peekCString p3 >>= \s -> print s where hstrL is a C function. The question is, if newCString fails to get allocation to s1 or s2, how must i handle this error?. Thanks for any help. gustavo
On Thu, Apr 24, 2003 at 11:26:18AM -0300, Gustavo Villavicencio wrote:
Hi all,
Suppose the next fragment
main = newCString s1 >>= \p1 -> newCString s2 >>= \p2 -> let p3 = hstrL p2 p1 in peekCString p3 >>= \s -> print s
where hstrL is a C function. The question is, if newCString fails to get allocation to s1 or s2, how must i handle this error?.
If newCString fails to allocate the buffer to store the string, it will later crash while trying to copy the string into the buffer. The justification is that malloc hardly fails due to virtual memory. If you have other function that return a null pointer you should have a look at the functions in Foreign.Marshal.Error . BTW if hstrL does not free the two strings your code has a space leak. If hstrL only uses the string, you can use withCString which uses alloca (allocation on the stack) which is faster anyway. Hope this helps, Axel.
The question is, if newCString fails to get allocation to s1 or s2, how must i handle this error?.
Using the normal Haskell98 IOError mechanisms: http://www.haskell.org/onlinereport/io-13.html More usefully, you can use the GHC extensions (also supported by Hugs): http://www.haskell.org/ghc/docs/latest/html/base/GHC.Exception.html of which the most useful are bracket and bracket_ which provide functionality like Java/C++'s try/finally syntax. bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c e.g., main = bracket (newCString s1) free $ \p1 -> bracket (newCString s2) free $ \p2 -> let p3 = hstrL p2 p1 in peekCString p3 >>= \s -> print s This code will take care to free the two strings even if an exception is raised. -- Alastair Reid alastair@reid-consulting-uk.ltd.uk Reid Consulting (UK) Limited http://www.reid-consulting-uk.ltd.uk/alastair/
The question is, if newCString fails to get allocation to s1 or s2, how must i handle this error?.
Using the normal Haskell98 IOError mechanisms:
http://www.haskell.org/onlinereport/io-13.html
More usefully, you can use the GHC extensions (also supported by Hugs):
http://www.haskell.org/ghc/docs/latest/html/base/GHC.Exception.html
Slight correction: the right library to use is Control.Exception: http://www.haskell.org/ghc/docs/latest/html/base/Control.Exception.html GHC.Exception is not indended for external consumption, as is the case with all the GHC.* libraries except for GHC.Exts - the clue is "Stability: internal" in the header. We should really omit these from the docs.
of which the most useful are bracket and bracket_ which provide functionality like Java/C++'s try/finally syntax.
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
e.g.,
main = bracket (newCString s1) free $ \p1 -> bracket (newCString s2) free $ \p2 -> let p3 = hstrL p2 p1 in peekCString p3 >>= \s -> print s
This code will take care to free the two strings even if an exception is raised.
In cases like the above, you almost certainly want to use withCString which also guarantees to free the string if an exception is raised. Cheers, Simon
participants (4)
-
Alastair Reid -
Axel Simon -
Gustavo Villavicencio -
Simon Marlow