source: project/wiki/location-and-c-string-star @ 36676

Last change on this file since 36676 was 31126, checked in by Mario Domenech Goulart, 5 years ago

Properly capitalize CHICKEN on the wiki directory (only first level).

I used the following shell script to change things:

while IFS= read -d $'\0' -r file ; do

sed -i 's/Chicken/CHICKEN/g' "$file"

done < <(find wiki -maxdepth 1 -type f -print0 )

Some files have been manually reverted after that, since some
substitutions don't apply:

  • friedly-chicken (repl banner)
  • survey2011 (Chicken in URI paths)
  • chickenista-guide (Chickenista)

I hope the link canonicalization thing will be on my side.

File size: 2.2 KB
Line 
1[[tags:ffi]]
2
3Say you have a C function called {{profile}} which allocates and
4returns a string, expecting you to free it.  The main return value is
5an {{int}}, the string pointer is returned by reference in a {{char**}}
6argument.  You may use {{let-location}} to easily handle the returned
7string, if you follow the recipe below.
8
9 ; int profile(const char *in, char **out);
10 (define profile
11   (foreign-lambda int "profile" (const c-string) (pointer c-string)))
12 
13 (let-location ((out c-string*))
14   (let ((rv (profile "LAMBDA-CALCULUS.ORG" (location out))))
15     (let ((out out))             ; clean up out
16       (if (eqv? rv 0)
17           (print out)
18           (error "profile error" rv)))))
19
20It's fine to use {{let-location}} with a {{c-string}} type.
21Internally, every time you dereference this type, CHICKEN calls
22{{##sys#peek-c-string}}, which creates a new scheme string and copies the
23C string in with {{strcpy()}}.
24
25However, is it safe to use a {{c-string*}} type to get its automatic
26free() behavior?  Yes, if you're careful.
27
28CHICKEN will call {{##sys#peek-and-free-c-string}} every time your
29location ({{out}}) is dereferenced.  This does a {{strcpy()}} ''plus'' a
30{{free()}}.  So, it is not safe to dereference {{out}} more than once
31during the flow of control, as it will cause a double-free and, worse,
32a reference to freed memory.  This also implies that if you do not
33refer to {{out}} at all, its memory will leak.
34
35A safe way to handle this situation is to bind all location
36variables to themselves in a surrounding let statement, which guarantees the free
37occurs exactly once.  It is safe to dereference {{c-string*}} locations even
38if they are NULL, as it will just return {{#f}} without calling {{free()}}.
39
40Of course, you may instead structure your code so you're sure the
41location is always dereferenced exactly once, when not NULL.  This happens
42to be true in the simple example above, in fact.  On the other hand,
43it is easy to accidentally violate this requirement, and the special
44behavior of {{out}} may not be apparent to readers of your code.
45
46This technique is also applicable for regular {{c-string}} locations that
47you use more than once, to avoid redundant strcpy() calls.
48
49--[[http://3e8.org/zb|zbigniew]]
Note: See TracBrowser for help on using the repository browser.