logo       

Re: peekCString stack overflow: msg#00007

lang.haskell.glasgow.bugs

Subject: Re: peekCString stack overflow


> Yes, I've run into this before. In fact this is one of those tricky
> problems where you can't quite get tail-recursion where you want it:
> (pseudo-ish code follows)
>
> peekCString ptr = do
> x <- peek ptr
> if x == '\0' then return [] else do
> xs <- peekCString (ptr + 1)
> return (x:xs)
>
> Any ideas? I seem to recall the ML folks have a hack for dealing with
> this.

Off the top of my head:

1) Compute length of C string.
(As usual, need to use seq on the '+1' argument.)
2) Scan from right to left, constructing the list.

peekCString ptr = do
l <- lenCString ptr 0
peekCString' ptr l []

lenCString ptr n = seq n $ do
c <- peek (ptr+n)
if c=='\0'
then return n
else lenCString ptr (n+1)

peekCString' ptr 0 r = return r
peekCString' ptr (n+1) r = do
c <- peek (ptr+n)
peekCString' ptr n (c:r)

I don't think this will leak.

Or, since making two passes seems ugly, construct the list in reverse and then
return the reversed list:

peekCString ptr = peekCString' ptr []
where
peekCString' ptr r = do
c <- peek ptr
if c == '\0'
then return (reverse r)
else peekCString' (ptr+1) (c:r)

I have a nasty feeling that reverse doesn't work in constant stack space
though so this probably doesn't work.

--
Alastair


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise