Can't access [dynamic] from struct after it's been converted to a rawptr

Hello all. I was working on a project and had a pretty simple struct that I was passing into another thread to work on. Inside this struct was a [dynamic]TMP, with TMP being another struct. Whenever I tried to access this, the program would puke. So I set about trying to duplicate it as simply as possible.

What I ended up with was this:

package qqq
import "core:fmt"

UNIT :: struct {
	i: int,
}

CHUNK :: struct {
	d1: [dynamic]^UNIT,
	d2: [dynamic]int,
}

main :: proc() {
	chunk := new(CHUNK)
	chunk^.d1 = make([dynamic]^UNIT)

	d1 := new(UNIT)
	d1.i = 1
	append(&chunk.d1, d1)
	append(&chunk.d2, 1)

	fmt.printf("%#v\n", chunk)

	fmt.printf("Original type d1: %T\nLength: %d\n", chunk.d1, len(chunk.d1))
	fmt.printf("Original type d2: %T\nLength: %d\n", chunk.d2, len(chunk.d2))

	rawpt1 := rawptr(&chunk)
	converted_chunk := cast(^CHUNK)rawpt1

	fmt.printf(
		"Converted back type d1: %T\nLength: %d\n",
		converted_chunk.d1,
		len(converted_chunk.d1),
	)
	fmt.printf(
		"Converted back type d2: %T\nLength: %d\n",
		converted_chunk.d2,
		len(converted_chunk.d2),
	)
}

I create my CHUNK, create two [dynamic] arrays, get the raw pointer, convert it back to a CHUNK, and print types and lengths.

Results:

&CHUNK{
        d1 = [
                0x6283F3471318,
        ],
        d2 = [
                1,
        ],
}
Original type d1: [dynamic]^UNIT
Length: 1
Original type d2: [dynamic]int
Length: 1
Converted back type d1: [dynamic]^UNIT
Length: 108318861759144
Converted back type d2: [dynamic]int
Length: 0

I’m super confused how a dynamic array of pointers gives me an incredibly huge number, but of int’s it’s 0. I added in a:

	fmt.printf("%#v\n", converted_chunk.d1[0])

and it prints:

&UNIT{
        i = 108318861759256,
}

But adding making that converted_chunk.d1[1] gives a seg fault.

My questions are:

  1. Am I doing it wrong?
  2. If not, is this expected behavior?
  3. Help? :smiley:

-Soldyrm

You turn the stack address of the chunk pointer into a chunk pointer here, which is not correct, as it will then read arbitrary stack memory as if it were a CHUNK. You should just cast chunk to rawptr directly.

3 Likes

Damn. I spent so long scratching my head over this. Thank you!

1 Like

Also, here you can just do chunk.d1, as it will implicitly dereference.
And for the printfs you can use printfln instead of adding the \n, if you want.

1 Like