Learning Ctypes

Hi everyone,

First of all, sorry if this is a dumb question, this is my 1st time using ctypes. I’m trying to use it to interact with a C struct that contains a char* field. I wrote a small function to test it out by writing a string into the struct and reading it back. Most of the time it works fine, but sometimes it doesn’t, and I can’t figure out why.

Here’s a simpler example of what I’m doing:

open Ctypes
open Foreign

(* Struct example *)
type data_struct
let data_struct : data_struct structure typ = structure "data_struct"
let field_str = field data_struct "str" (ptr char)
let () = seal data_struct

let rec read_string ptr acc i =
  let c = !@(ptr +@ i) in
  if c = '\000' then acc else read_string ptr (acc ^ String.make 1 c) (i + 1)

(* Test function *)
let () =
  let run_test s =
    let data = make data_struct in
    (* Caaray and pointer to it *)
    let str_array = CArray.of_string s in
    let str_ptr = CArray.start str_array in
    setf data field_str str_ptr;
    (* Read back the value *)
    let read_ptr = getf data field_str in
    let read_str = read_string read_ptr "" 0 in

    assert (read_str = s)
  in

  for i = 1 to 1000 do
    Printf.printf "Test %d\n" i;
    let test_str = "Hello, this is a test string " ^ string_of_int i in
    run_test test_str
  done

I don’t really know why this happens though, from looking at the outputs when it fails it looks like random data, which I assume is because memory is freed, but how can that happen when the value is still used in the function?

Thank you for your time.

EDIT: in fact I dont know… but I noticed that for me the code fails with native compilation (ocamlopt) but not with ocamlc

EDIT2: in fact, after some testing, the error is due to str_array being collected just before (or during) reading the string.

conclusion: you should save str_array and “use” it after reading the string

1 Like

I see. Thank you for your help!