Hello, ive got an array list of items. where the items don’t get removed from the list, but set to undefined. ive got a setup where the list is only freed at just before program exit.
when i deinit the item at say index 0, i want ALL existing pointers to it invalid, as in, when element 0 has its data updated, the existing pointers to it shouldn’t work, unless a new pointer was requested.
so how do i invalidate existing pointers?
var foo: std.ArrayList(BarType) = .empty;
foo.append(allocator, 1);
return &foo.items[0];
// .... another function
var element = &foo.items[0];
element.deinit();
element.* = undefined;
// now that the item deinit and set to undefined, any existing pointers to element 0 should be invalid and no longer work, new pointers must be requested.
Hmm, should then introduce a tag, or would an optional be more appropriate?
the type is a struct containing metadata (and a ptr) of memory owned by the GPU
the type is absolutely capable of having more fields. it’s not under a size requirement (well, as long as its not kilobytes big ^^).
Due to optionals not currently being able to take advantage of padding or invalid states, using an optional will increase the size according to alignment.
Whereas using an additional field might not increase the size at all, but could be as bad as an optional depending on if space is available (padding).
There are ways to get around that, but without knowing more about your data (I mean quite detailed), I can’t really recommend anything. Look into data oriented design for all the things I can’t be bothered explaining.
An invalid state would use no extra space, but requires your type to have at least 1 invalid state, and ideally one that is cheap to check.
But an optional forces the semantics you want, the others don’t, though you could make an api that does enforce it.
This sounds a lot like ‘generation-counted index-handles’ could be a good match, they’re basically designed for fixing dangling pointer problems in memory-unsafe languages with minimal runtime overhead, not a very good match for OOP code though (e.g. ‘object methods’ being called outside the system which ‘owns’ the object).
See my 2018 blog post (the concept has been around much longer though, at least to the early 2000s or late 1990s):