【问题标题】:C++ - Deleting an object before returning itC++ - 在返回之前删除一个对象
【发布时间】:2015-12-12 19:12:27
【问题描述】:

我正在阅读 TensorFlow 教程,并在深入研究代码时遇到了以下问题:

OpDefBuilder& RegisterOp(StringPiece name) {
   VLOG(1) << "RegisterOp: " << name;
   OpDefBuilder* b = new OpDefBuilder(name);
   OpRegistry::Global()->Register([b]() -> ::tensorflow::OpDef {
     OpDef op_def;
     TF_QCHECK_OK(b->Finalize(&op_def));
     delete b;
      return op_def;
   });
   return *b;
}

Register函数声明如下:

void OpRegistry::Register(std::function<OpDef(void)> func);

上面的 sn-p 似乎是在用OpDefBuilder* b = new OpDefBuilder(name); 创建一个OpDefBuilder* 对象

然后它在作为参数传递给OpRegistry::Global()-&gt;Register(...) 的 lambda 函数中使用delete b; 销毁该对象。然后它返回相同的对象(!)。假设 lambda 函数在 Register(...) 内被调用(并且根据我的理解确实被调用),这对我来说没有意义。

我不是 C++ 初学者,但我以前从未见过这种做法。我在这里错过了什么?

完整的 .cpp 文件(包括 Register(...) 定义)是 here

我们将不胜感激。

【问题讨论】:

  • 如果返回op_def,则行为未定义。您正在返回对局部变量的引用。可能这段代码几乎没有针对该场景进行过测试。
  • @up 他不是按值返回吗? -&gt; ::tensorflow::OpDef
  • @Fireho - 是的,我错过了。返回的是 lambda,而不是整个函数。
  • 什么是TF_QCHECK_OK(b->Finalize(&op_def));?这可能与场景有很大关系。
  • 通常,当您向某人注册某事时,该某事会在稍后被调用,而不是当场调用。否则,该方法的正确名称不应该是Register,而应该是其他名称。 Register 表示使用“观察者”设计模式,不是“访问者”设计模式。

标签: c++ tensorflow


【解决方案1】:

OpDef 的构造函数将initialized 成员设置为false。但是,传递给Register 的函数对象仅在此成员为true 时才被调用。即注册不调用函数deleteing对象。

据说,该函数稍后会执行,此时对象会被清理。这个部分在我看来有点可疑,但没有深入挖掘,似乎没有明显的错误。

【讨论】:

    【解决方案2】:

    很难说没有Register 的代码,但很可能它不会立即执行传递给它的 lambda。它可能会存储它以供以后执行,作为某种清理。

    【讨论】:

      【解决方案3】:

      我大约 90% 确信这是一个实际的错误。在一些对操作注册表更了解的人的帮助下,我正在深入研究它。会更新。

      (我相信发生的事情是,在每次使用注册表时,initialized_ 都是错误的——即,在注册表上进行任何查找或其他操作之前,所有操作都已注册。这条路径显然是正确的,因为操作被扔到延迟队列中,因此删除直到稍后才会生效。但是,如果稍后注册操作,它闻起来像一个错误。这就是我正在检查并尝试为其创建测试用例的内容。 )

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-08
        • 1970-01-01
        • 2020-09-18
        • 2014-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多