From 2e4de7b67dcea307cbb306739d71a6d983165684 Mon Sep 17 00:00:00 2001 From: karroffel Date: Fri, 19 Jan 2018 11:40:50 +0100 Subject: [PATCH] Don't leak memory from Ref<>() --- binding_generator.py | 2 +- include/core/Ref.hpp | 93 +++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 58 deletions(-) diff --git a/binding_generator.py b/binding_generator.py index 6af6d0b..bdea354 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -341,7 +341,7 @@ def generate_class_implementation(icalls, used_classes, c): if is_enum(method["return_type"]): return_statement += "return (" + remove_enum_prefix(method["return_type"]) + ") " elif is_reference_type(method["return_type"]): - return_statement += "return Ref<" + strip_name(method["return_type"]) + ">::__internal_constructor("; + return_statement += "return Ref<" + strip_name(method["return_type"]) + ">("; else: return_statement += "return " + ("(" + strip_name(method["return_type"]) + " *) " if is_class_type(method["return_type"]) else "") else: diff --git a/include/core/Ref.hpp b/include/core/Ref.hpp index 345b455..043db57 100644 --- a/include/core/Ref.hpp +++ b/include/core/Ref.hpp @@ -10,24 +10,6 @@ template class Ref { T *reference; - void ref(const Ref &from) - { - if (from.reference == reference) return; - - unref(); - - reference = from.reference; - if (reference) reference->reference(); - } - - void ref_pointer(T *r) - { - if (!r) return; - - if (r->init_ref()) reference = r; - } - - public: inline bool operator==(const Ref &r) const { @@ -73,28 +55,37 @@ public: void operator=(const Ref &from) { - ref(from); + if (reference) + unref(); + + if (from.reference) { + reference = from.reference; + reference->reference(); + } else { + reference = nullptr; + } } template void operator=(const Ref &from) { - Ref n((T *) from.ptr()); - ref(n); + if (reference) + unref(); + + if (from.reference) { + reference = (T *) from.reference; + reference->reference(); + } else { + reference = nullptr; + } } void operator=(const Variant &variant) { - T *r = (T *) (Object *) variant; - if (!r) { + if (reference) unref(); - return; - } - - Ref re; - re.reference = r; - ref(re); - re.reference = nullptr; + + reference = (T *) (Object *) variant; } operator Variant() const @@ -105,22 +96,27 @@ public: template Ref(const Ref &from) { - if (from.ptr()) - ref_pointer((T *) from.ptr()); - else + if (from.reference) { + reference = (T *) from.reference; + reference->reference(); + } else { reference = nullptr; + } } Ref(const Ref &from) { - reference = nullptr; - ref(from); + if (from.reference) { + reference = from.reference; + reference->reference(); + } else { + reference = nullptr; + } } Ref(T *r) { - r->reference(); reference = r; } @@ -129,28 +125,9 @@ public: Ref(const Variant &variant) { - reference = nullptr; - T *r = (T *) (Object *) variant; - if (!r) { - unref(); - return; - } - - Ref re; - re.reference = r; - ref(re); - re.reference = nullptr; + reference = (T *) (Object *) variant; } - template - static Ref __internal_constructor(T_Other *r) - { - Ref ref; - ref.reference = (T *) r; - return ref; - } - - inline bool is_valid() const { return reference != nullptr; } inline bool is_null() const { return reference == nullptr; } @@ -164,7 +141,9 @@ public: void instance() { - ref(new T); + unref(); + + reference = new T; } Ref()