From 6bdd5ed35f1d07cfbef8c585afd7cba2f6884a6e Mon Sep 17 00:00:00 2001 From: Michael Sollami Date: Mon, 20 Jul 2026 18:53:16 -0400 Subject: [PATCH] Fix one-time leak of $MaxExtraPrecision init constant system_constants_init registered $MaxExtraPrecision via symtab_add_own_value but never freed the expr_new_real(50.0) temporary. add_rule inc-refs (expr_copy) its replacement, so the caller retains ownership of its own reference and must free it -- as register_system_constant already does for the other constants. Capture the value in a temp and free it, eliminating the single 64-byte Real leak reported by macOS leaks/valgrind at startup. --- docs/spec/changelog/2026-07-20.md | 12 ++++++++++++ src/core.c | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/spec/changelog/2026-07-20.md b/docs/spec/changelog/2026-07-20.md index 7f20661f..e48698d8 100644 --- a/docs/spec/changelog/2026-07-20.md +++ b/docs/spec/changelog/2026-07-20.md @@ -3,6 +3,18 @@ Feature additions and fixes recorded during this week. +### Fixed + +- **`$MaxExtraPrecision` init leak** (beads-planning-dbl). The inline + `$MaxExtraPrecision` registration block in `system_constants_init` + (`src/core.c`) passed an `expr_new_real(50.0)` temporary to + `symtab_add_own_value` without freeing it — a 64-byte `EXPR_REAL` leak at + startup (`symtab_add_own_value` deep-copies its replacement, so the caller + retains ownership of its own reference). Fixed by capturing the value in a + local and `expr_free`-ing it, mirroring the `register_system_constant` helper. + macOS `leaks` on `trace_tests` now reports 0 leaks (was "1 leak for 64 total + leaked bytes" rooted at `system_constants_init -> expr_new_real`). + ## Numeric loop fast-path + iteration allocation cleanups (2026-07-20) Closed the large gap to Mathematica on tight numeric loops. Reference (10^6 diff --git a/src/core.c b/src/core.c index a61faeaf..114baa5b 100644 --- a/src/core.c +++ b/src/core.c @@ -163,8 +163,10 @@ static void system_constants_init(void) { * other constants it is user-settable, so it is NOT marked Protected. */ { Expr* sym = expr_new_symbol(SYM_DollarMaxExtraPrecision); - symtab_add_own_value("$MaxExtraPrecision", sym, expr_new_real(50.0)); + Expr* val = expr_new_real(50.0); + symtab_add_own_value("$MaxExtraPrecision", sym, val); expr_free(sym); + expr_free(val); } register_system_constant("$MachineEpsilon", expr_new_real(DBL_EPSILON)); register_system_constant("$MinMachineNumber", expr_new_real(DBL_MIN));