Skip to content

Commit 7301dc6

Browse files
authored
Update gethostname example (#36082)
Add `GC.@preserve` to code and a short explanation
1 parent a5c08c4 commit 7301dc6

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

doc/src/manual/calling-c-and-fortran-code.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,24 @@ function gethostname()
142142
hostname, sizeof(hostname))
143143
Base.systemerror("gethostname", err != 0)
144144
hostname[end] = 0 # ensure null-termination
145-
return unsafe_string(pointer(hostname))
145+
return GC.@preserve hostname unsafe_string(pointer(hostname))
146146
end
147147
```
148148

149149
This example first allocates an array of bytes. It then calls the C library function `gethostname`
150-
to populate the array with the hostname. Finally, it takes a pointer to the hostname buffer, and converts the
151-
pointer to a Julia string, assuming that it is a NUL-terminated C string. It is common for C libraries
152-
to use this pattern of requiring the caller to allocate memory to be passed to the callee and
153-
populated. Allocation of memory from Julia like this is generally accomplished by creating an
154-
uninitialized array and passing a pointer to its data to the C function. This is why we don't
155-
use the `Cstring` type here: as the array is uninitialized, it could contain NUL bytes. Converting
156-
to a `Cstring` as part of the [`ccall`](@ref) checks for contained NUL bytes and could therefore
157-
throw a conversion error.
150+
to populate the array with the hostname. Finally, it takes a pointer to the hostname buffer, and
151+
converts the pointer to a Julia string, assuming that it is a NUL-terminated C string.
152+
153+
It is common for C libraries to use this pattern of requiring the caller to allocate memory to be
154+
passed to the callee and populated. Allocation of memory from Julia like this is generally
155+
accomplished by creating an uninitialized array and passing a pointer to its data to the C function.
156+
This is why we don't use the `Cstring` type here: as the array is uninitialized, it could contain
157+
NUL bytes. Converting to a `Cstring` as part of the [`ccall`](@ref) checks for contained NUL bytes
158+
and could therefore throw a conversion error.
159+
160+
Deferencing `pointer(hostname)` with `unsafe_string` is an unsafe operation as it requires access to
161+
the memory allocated for `hostname` that may have been in the meanwhile garbage collected. The macro
162+
[`GC.@preserve`](@ref) prevents this from happening and therefore accessing an invalid memory location.
158163

159164
## Creating C-Compatible Julia Function Pointers
160165

0 commit comments

Comments
 (0)