Skip to content

Commit ab24986

Browse files
matzclaude
andcommitted
gc.c: remove all matching entries in mrb_gc_unregister()
Previously only the first match was removed, leaking duplicate entries when the same object was registered multiple times. Use two-pointer compaction for O(N) removal. Fixes mruby#6760. Co-authored-by: Claude <noreply@anthropic.com>
1 parent c2b5881 commit ab24986

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

src/gc.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,15 +541,15 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
541541
if (!mrb_array_p(table)) return;
542542
struct RArray *a = mrb_ary_ptr(table);
543543
mrb_ary_modify(mrb, a);
544-
mrb_int len = ARY_LEN(a)-1;
544+
mrb_int len = ARY_LEN(a);
545545
mrb_value *ptr = ARY_PTR(a);
546-
for (mrb_int i = 0; i <= len; i++) {
547-
if (mrb_ptr(ptr[i]) == mrb_ptr(obj)) {
548-
ARY_SET_LEN(a, len);
549-
memmove(&ptr[i], &ptr[i + 1], (len - i) * sizeof(mrb_value));
550-
break;
546+
mrb_int w = 0;
547+
for (mrb_int r = 0; r < len; r++) {
548+
if (mrb_ptr(ptr[r]) != mrb_ptr(obj)) {
549+
ptr[w++] = ptr[r];
551550
}
552551
}
552+
ARY_SET_LEN(a, w);
553553
}
554554

555555
MRB_API struct RBasic*

0 commit comments

Comments
 (0)