From b67eff47d2210a6dce70f81a4412bc5e60fac03f Mon Sep 17 00:00:00 2001 From: Pierre-Antoine Bannier Date: Fri, 11 Sep 2026 13:49:55 +0200 Subject: [PATCH] fix: free model backend, buffer and context when the model is dropped sam3_load_model returned std::make_shared(), and sam3_model has no destructor. Nothing ever called sam3_free_model, so each loaded model leaked its weight buffer, ggml context and backend (~42 MB per load for SAM2.1-tiny q8_0, on CPU and Metal). It also leaked on every early-return failure path inside the loader. Give the shared_ptr a deleter that calls sam3_free_model. The function nulls what it frees, so an explicit call before release stays safe. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01M2qLmQ9ag49hT61V6i9qAq --- sam3.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sam3.cpp b/sam3.cpp index 43d88a8..edabaf9 100644 --- a/sam3.cpp +++ b/sam3.cpp @@ -3240,7 +3240,10 @@ std::shared_ptr sam3_load_model(const sam3_params& params) { fprintf(stderr, "%s: %s format v%d, ftype %d, %d tensors\n", __func__, is_sam2 ? "SAM2" : "SAM3", version, ftype, n_tensors); - auto model = std::make_shared(); + std::shared_ptr model(new sam3_model(), [](sam3_model* m) { + sam3_free_model(*m); + delete m; + }); { ggml_type wtype; switch (ftype) {