Fix mutation of input iterators in seq_arr_erase_it
The seq_arr_erase_it function was modifying start_it during the free_func loop, which led to incorrectly apply the free_func on the whole array. This commit makes sure the elements "freed" are only those in the range and not the whole seq_arr. * Fixes the logic by introducing a temporary iterator for the free loop, preserving start_it and end_it for correct offset calculations. * Adds a regression test in test_seq_arr to verify that only the selected subrange is erased and that free_func is called exactly on that range.
This commit is contained in:
@@ -123,11 +123,10 @@ void seq_arr_erase_it(seq_arr_t* arr, void* start_it, void* end_it, void (*free_
|
||||
return;
|
||||
|
||||
if (free_func != NULL) {
|
||||
void* start_it = seq_arr_front(arr);
|
||||
void* end_it = seq_arr_end(arr);
|
||||
while (start_it != end_it) {
|
||||
free_func(start_it);
|
||||
start_it = seq_arr_next(arr, start_it);
|
||||
void* it = start_it;
|
||||
while (it != end_it) {
|
||||
free_func(it);
|
||||
it = seq_arr_next(arr, it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,13 @@ static int compar(const void* m0, const void* m1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int free_func_call_count = 0;
|
||||
|
||||
static void dummy_free_func(void* it)
|
||||
{
|
||||
++free_func_call_count;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
seq_arr_t arr = {0};
|
||||
@@ -83,6 +90,19 @@ int main()
|
||||
void* it = bsearch(&key, base, nmemb, size, compar);
|
||||
assert(seq_arr_dist(&arr, seq_arr_front(&arr), it) == 4);
|
||||
|
||||
// Regression test: erase a partial range only
|
||||
// Erase 92, 93, 94 (i.e., indices 1 to 3)
|
||||
int* start = seq_arr_at(&arr, 1);
|
||||
int* end = seq_arr_at(&arr, 4);
|
||||
seq_arr_erase_it(&arr, start, end, dummy_free_func);
|
||||
|
||||
// Now values should be: [91, 95, 96, 97, 98, 99]
|
||||
assert(free_func_call_count == 3);
|
||||
assert(seq_arr_size(&arr) == 6);
|
||||
assert(*(int*)seq_arr_at(&arr, 0) == 91);
|
||||
assert(*(int*)seq_arr_at(&arr, 1) == 95);
|
||||
assert(*(int*)seq_arr_at(&arr, 5) == 99);
|
||||
|
||||
// Free data structure
|
||||
seq_arr_free(&arr, NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user