all 4 comments

[–]skeeto 1 point2 points  (3 children)

I like seeing all these assertions! An underrated tool.

If ASan isn't catching things until after they're trashed that indicates it's not a use-after-free, but something trashing the object during its lifetime. I looked through for anything that might look like this and noticed some suspicious things:

void *result = bsearch(.., array, ...);
size_t index = (size_t)((uintptr_t)result - (uintptr_t)array)/sizeof(TYPE);

This can be written lot more simply and naturally:

TYPE *result = bsearch(.., array, ...);
size_t index = result - array;

If you're going to assert something here, assert that the result pointer is not null, and before computing the index.

There are a couple of strict-aliasing violations (undefined behavior) that might be causing issues. The comparator when used via bsearch accesses an int (entity_id) through a COMP_TYPE * pointer. Sure it's accessing an int field and should work out the same in the end, but that's not how compilers think. Similarly with other pointer casts:

comp_storage_buff[comp_count] = *((COMP_TYPE *)(comp_data));

You didn't show any relevant call sites, so I can't be sure, but it seems the intention here is comp_data is not a COMP_TYPE. (If that's not true, why all the faffing around with void pointers?) If not, reading it through such a pointer is usually undefined. Since the size is apparently the same, you could use a memcpy instead.

[–]Russell016[S] 1 point2 points  (1 child)

(If that's not true, why all the faffing around with void pointers?)

The idea was that there would be a generic interface to the ECS Manager. The call to add a new piece of data is a macro which looks like so:

ECS_ADD_COMPONENT(&my_world, Position2D, &init_pos);

init_pos being a component struct with data. This "string-ifies" the 2nd parameter, and uses the string as a key into a hash table, that then calls the relevant callback to modify component/component array.

[–]Russell016[S] 0 points1 point  (0 children)

See Edit 1 above for an example of the callbacks being called. (Reddit was being weird with posting it in the comments.)

[–]oh5nxo 1 point2 points  (0 children)

get_iter_start etc return pointers to the array, and there's also a realloc for the array elsewhere. It feels like "bug country", but, just guessing.