In the following small sample program, input is read from stdin
. Printing the string value works inside read_input
, but not in main
. Surprisingly, the length (len
) of the string does output in main
, though the string output is blank.
main :: proc() {
fmt.print("$ ")
input := read_input()
// This will output the proper length
fmt.println("returned string length:", len(input))
// This will be empty
fmt.println("returned string: ", input)
}
read_input :: proc() -> string {
buf: [256]byte
num_bytes, err := os.read(os.stdin, buf[:])
if err < 0 {
return "Error reading from stdin"
}
str := string(buf[:num_bytes - 1])
// this will output the proper number of bytes
fmt.println("bytes read: ", num_bytes)
// this will output the string entered, minus the newline
fmt.println("read string: ", str)
return str
}
Example run/output:
$ hello
bytes read: 6
read string: hello
returned string length: 5
returned string:
I've discovered that returning strings.clone(str)
works but I'm not really understanding the problem above.
In Odin string
is just a view over underlaying data buffer. In your case it points to buf
which is local to read_input
procedure. Once read_input
returns its stack memory is gone, but returned string still points to it.
strings.clone(str)
works because it allocates memory for a string copy and return string which points into this memory. In this case you'll need to delete
it in main
to avoid memory leak.