From 8938a9b0accdf577e2c8ec103d9556227b36c875 Mon Sep 17 00:00:00 2001
From: Yu Yang <yuyang18@baidu.com>
Date: Tue, 17 Oct 2017 20:18:03 -0700
Subject: [PATCH] Correct implement BlockDesc destructor (#4882)

---
 paddle/framework/block_desc.cc | 20 ++++++++++++++++++--
 paddle/framework/block_desc.h  |  9 +++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/paddle/framework/block_desc.cc b/paddle/framework/block_desc.cc
index 47b75228cd..ba970254e5 100644
--- a/paddle/framework/block_desc.cc
+++ b/paddle/framework/block_desc.cc
@@ -72,13 +72,13 @@ std::vector<OpDescBind *> BlockDescBind::AllOps() const {
 void BlockDescBind::Flush() {
   if (need_update_) {
     auto &op_field = *this->desc_->mutable_ops();
-    op_field.Clear();
+    this->ClearPBOps();
     op_field.Reserve(static_cast<int>(ops_.size()));
     for (auto &op_desc : ops_) {
       op_field.AddAllocated(op_desc->Proto());
     }
     auto &var_field = *this->desc_->mutable_vars();
-    var_field.Clear();
+    this->ClearPBVars();
     var_field.Reserve(static_cast<int>(vars_.size()));
     for (auto &var_desc : vars_) {
       var_field.AddAllocated(var_desc.second->Proto());
@@ -99,5 +99,21 @@ BlockDesc *BlockDescBind::Proto() {
   return desc_;
 }
 
+void BlockDescBind::ClearPBOps() {
+  auto ops = this->desc_->mutable_ops();
+  while (!ops->empty()) {
+    // we do not own the OpDesc, so release the ownership.
+    ops->ReleaseLast();
+  }
+}
+
+void BlockDescBind::ClearPBVars() {
+  auto vars = this->desc_->mutable_vars();
+  while (!vars->empty()) {
+    // we do not own the VarDesc, so release the ownership.
+    vars->ReleaseLast();
+  }
+}
+
 }  // namespace framework
 }  // namespace paddle
diff --git a/paddle/framework/block_desc.h b/paddle/framework/block_desc.h
index 9fb88f9632..dd7b1228be 100644
--- a/paddle/framework/block_desc.h
+++ b/paddle/framework/block_desc.h
@@ -36,6 +36,11 @@ class BlockDescBind {
   BlockDescBind(ProgramDescBind *prog, BlockDesc *desc)
       : prog_(prog), desc_(desc), need_update_(false) {}
 
+  ~BlockDescBind() {
+    this->ClearPBVars();
+    this->ClearPBOps();
+  }
+
   int32_t ID() const { return desc_->idx(); }
 
   int32_t Parent() const { return desc_->parent_idx(); }
@@ -60,6 +65,10 @@ class BlockDescBind {
 
   BlockDesc *Proto();
 
+ private:
+  void ClearPBOps();
+  void ClearPBVars();
+
   // FIXME(yuyang18): backward will access private data of BlockDesc.
   // Mark it public temporary. We can fix it later.
  public: