From 23e96cfe3c410681ae23e3b63ca5304b86d6da84 Mon Sep 17 00:00:00 2001 From: webbrain-one <295484252+webbrain-one@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:47:26 +0300 Subject: [PATCH] Fix memory leak in Value::operator+ Prevent a circular reference by capturing a raw pointer to the output node in the _backward lambda instead of a shared_ptr. --- cpp-micrograd/engine.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/cpp-micrograd/engine.cpp b/cpp-micrograd/engine.cpp index bfbcb0e..05c17f6 100644 --- a/cpp-micrograd/engine.cpp +++ b/cpp-micrograd/engine.cpp @@ -92,9 +92,10 @@ std::shared_ptr Value::operator+(const std::shared_ptr& other) { auto out = std::make_shared(data + other->data, out_prev, "+"); - out->_backward = [this, other, out] { - grad += out->grad; - other->grad += out->grad; + Value* weak_ref = out.get(); + out->_backward = [this, other, weak_ref] { + grad += weak_ref->grad; + other->grad += weak_ref->grad; }; return out; @@ -144,8 +145,9 @@ std::shared_ptr Value::pow(const std::shared_ptr& other) { auto out = std::make_shared(std::pow(data, other->data), out_prev, "^"); - out->_backward = [this, other, out] { - grad +=other->data * std::pow(data, other->data - 1) * out->grad; + Value* weak_ref = out.get(); + out->_backward = [this, other, weak_ref] { + grad +=other->data * std::pow(data, other->data - 1) * weak_ref->grad; }; return out; @@ -182,9 +184,10 @@ std::shared_ptr Value::operator*(const std::shared_ptr& other) { auto out = std::make_shared(data * other->data, out_prev, "*"); - out->_backward = [this, other, out] { - grad += other->data * out->grad; - other->grad += data * out->grad; + Value* weak_ref = out.get(); + out->_backward = [this, other, weak_ref] { + grad += other->data * weak_ref->grad; + other->grad += data * weak_ref->grad; }; return out;