From: Hwankyu Jhun Date: Tue, 27 Oct 2020 10:28:35 +0000 (+0900) Subject: Fix memory leak X-Git-Tag: accepted/tizen/6.0/unified/20201110.010734~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=405c9725579862f5c7086814c1df36e51ab5b742;p=platform%2Fcore%2Fbase%2Fbundle.git Fix memory leak Change-Id: I64962cb9633c6f9d774723c443e402e4fcf82d57 Signed-off-by: Hwankyu Jhun --- diff --git a/include/bundle_cpp.h b/include/bundle_cpp.h index a02c439..3b71501 100644 --- a/include/bundle_cpp.h +++ b/include/bundle_cpp.h @@ -65,8 +65,9 @@ class EXPORT_API Bundle final { * @since_tizen 5.5 * @param[in] handle The handle for type bundle_keyval_t * @param[in] name The key string + * @param[in] own True if this object owns the handle */ - KeyInfo(const bundle_keyval_t* handle, std::string name); + KeyInfo(const bundle_keyval_t* handle, std::string name, bool own = false); /** * @brief Destructor. diff --git a/src/bundle_cpp.cc b/src/bundle_cpp.cc index 617aecc..4cc9808 100644 --- a/src/bundle_cpp.cc +++ b/src/bundle_cpp.cc @@ -82,18 +82,23 @@ Bundle::Bundle(const Bundle& b) throw std::bad_alloc(); } -Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name) - : impl_(new Impl(this, handle, std::move(name))) { +Bundle::KeyInfo::KeyInfo(const bundle_keyval_t* handle, std::string name, + bool own) + : impl_(new Impl(this, handle, std::move(name), own)) { } Bundle::KeyInfo::~KeyInfo() { + if (impl_ && impl_->handle_ && impl_->own_) + bundle_keyval_free(const_cast(impl_->handle_)); } Bundle::KeyInfo::Impl::~Impl() = default; + Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent, const bundle_keyval_t* handle, - std::string name) - : handle_(handle), name_(name), parent_(parent) { + std::string name, + bool own) + : handle_(handle), name_(name), parent_(parent), own_(own) { } Bundle::KeyInfo::Impl::Impl(Bundle::KeyInfo* parent) : parent_(parent) { @@ -109,28 +114,35 @@ Bundle::KeyInfo::KeyInfo(const KeyInfo& k) Bundle::KeyInfo& Bundle::KeyInfo::operator = (const Bundle::KeyInfo& k) { if (this != &k) { + if (impl_->handle_ && impl_->own_) + bundle_keyval_free(const_cast(impl_->handle_)); + impl_->handle_ = bundle_keyval_dup(k.impl_->handle_); impl_->name_ = k.impl_->name_; if (impl_->handle_ == nullptr) throw std::bad_alloc(); + + impl_->own_ = true; } return *this; } Bundle::KeyInfo::KeyInfo(Bundle::KeyInfo&& k) noexcept { - impl_ = std::unique_ptr(new Impl(this)); - impl_->handle_ = k.impl_->handle_; - impl_->name_ = k.impl_->name_; - k.impl_->handle_ = nullptr; - k.impl_->name_ = ""; + impl_ = std::move(k.impl_); + impl_->parent_ = this; } Bundle::KeyInfo& Bundle::KeyInfo::operator = (Bundle::KeyInfo&& k) noexcept { if (this != &k) { + if (impl_->handle_ && impl_->own_) + bundle_keyval_free(const_cast(impl_->handle_)); + impl_->handle_ = k.impl_->handle_; impl_->name_ = k.impl_->name_; + impl_->own_ = k.impl_->own_; k.impl_->handle_ = nullptr; k.impl_->name_ = ""; + k.impl_->own_ = false; } return *this; } @@ -177,7 +189,9 @@ Bundle& Bundle::operator = (Bundle&& b) noexcept { impl_->handle_ = b.impl_->handle_; b.impl_->handle_ = nullptr; impl_->own_ = b.impl_->own_; + b.impl_->own_ = false; impl_->copy_ = b.impl_->copy_; + b.impl_->copy_ = false; } return *this; } @@ -192,7 +206,7 @@ std::vector Bundle::GetKeys() { bundle_foreach(impl_->handle_, [](const char *key, const int type, const bundle_keyval_t *kv, void *user_data) { auto* v = static_cast*>(user_data); - v->emplace_back(kv, key); + v->emplace_back(kv, key, false); }, &v); return v; diff --git a/src/bundle_cpp_implementation.h b/src/bundle_cpp_implementation.h index 907b9de..bf7c38c 100644 --- a/src/bundle_cpp_implementation.h +++ b/src/bundle_cpp_implementation.h @@ -31,16 +31,17 @@ class Bundle::KeyInfo::Impl { private: Impl(Bundle::KeyInfo* parent, const bundle_keyval_t* handle, - std::string name); + std::string name, bool own); explicit Impl(Bundle::KeyInfo* parent); private: friend class Bundle::KeyInfo; private: - const bundle_keyval_t* handle_; + const bundle_keyval_t* handle_ = nullptr; std::string name_; Bundle::KeyInfo* parent_; + bool own_ = false; }; class Bundle::Impl {