Memory being incorrectly allocated in volatile space? (Probably a C language question.)

Okay bear with me, this requires some context and is likely my bumbling around with C for the first time in 12 years.

I'm working on a 3D rasterizing setup, and as part of that I'm laying down the scaffolding of Vector3, Tri, and Mesh. I want everything to point back to the original Vector3 in space, so it's pointers all the way down.

struct definitions
struct Vector3
{
	float x, y, z;
};

struct Tri
{
	struct Vector3* p[3];
};

struct Mesh
{
	int length;
	struct Tri** f;
};

I have a set of functions Vector3_make, Tri_make, and a test Cube_make for a Mesh. Inspecting the results of all of these in Visual Studio's step-through inspector indicates that everything is being set up correctly. I've attached the source for those methods, symbols.c.
symbols.zip (628 Bytes)

Here's where it gets weird. I initially tried instantiating cube in eventHandler on kEventInit. cube looked great in the inspector, but by the time it got to update the pointer targets were completely different, seemingly random memory.

I initialized it in update instead as follows:

struct Mesh cube;
static int update(void* userdata)
{
	if (frame_count == 0) // Init
	{
		Cube_make(100, &cube);
	}

	PlaydateAPI* pd = userdata;
	pd->graphics->clear(kColorWhite);
        ...

And from the inspector's point of view, the pointer targets are as expected until pd->graphics->clear is called.

Before:

After:

Vector3D and Tri objects don't seem to be affected. I've been able to reference those across multiple updates. That tells me it's probably something to do with how I've set up the Mesh struct.

Any guidance is very welcome. Let me know if you need to see any other parts of the code.

All your Vector3 p1p8, Tri southbottom2, and faces (i.e. everything that makes up your mesh except the 12 bytes for the struct Mesh cube) are local variables of the Cube_make function, they are on the stack and go out of scope when that function returns. Further function calls reuse that stack space and overwrite your data with their own local variables. You should never take the address of a local variable using the & operator and then store the pointer obtained that way in something that outlives the function call.

You’ll need to store your vectors, triangles, and triangle pointers in something more long-lived, either global (or static) variables (as you already do with struct Mesh cube), or memory allocated by playdate->system->realloc(). Since the Cube_make function expects the caller to allocate space for the Mesh and pass a pointer to it, it should probably do the same with space for the Vector3s and Tris and Tri*s.

1 Like

Thank you so much, that makes a lot of sense.