【问题标题】:Lambda function, segmentation fault preventLambda函数,防止分段错误
【发布时间】:2016-05-12 14:12:25
【问题描述】:

我有一个指向我传递给 lambda 函数的对象的指针。由于 lambda 函数在初始方法调用后 1 秒被调用,因此对象有时不再有效,从而导致分段错误。

如何在使用之前验证该项目在 lambda 函数中仍然有效?

这是我使用 lambda 函数的方法的样子:

void myTab::myMethod(QStandardItem *item)
{
    QColor blue(0, 0, 128, 20); 
    QBrush brush(blue);
    item->setBackground(brush);

    //Restore background after 1000ms
    QTimer::singleShot(1000, [item, this]() mutable {
        item->setBackground(Qt::transparent);     //<-need some advice here
    });
}

【问题讨论】:

  • mutable 的意义何在?为什么会捕获this
  • @Alex -- 不要认为这是正确的 dup -- 问题不是空的,而是指向空闲内存
  • 他的问题不是如何检查指针是否有效,即它是否不是空指针?
  • Nvm,我看错了问题。

标签: c++ lambda segmentation-fault


【解决方案1】:

如何在使用之前验证该项目在 lambda 函数中仍然有效?

最简单的方法是让 item 成为一个 shared_ptr&lt;QStandardItem&gt;,您的 lambda 只会获得一个副本。这保证了该项目的寿命足够长:

void myTab::myMethod(std::shared_ptr<QStandardItem> item)
{
    QColor blue(0, 0, 128, 20); 
    QBrush brush(blue);
    item->setBackground(brush);

    //Restore background after 1000ms
    QTimer::singleShot(1000, [item]{
        item->setBackground(Qt::transparent);
    });
}

否则,您无法从指针中真正判断它是否指向仍然有效的对象。或者其他奇怪的东西,比如对象被删除了,一个新的对象恰好被分配在同一个内存中,现在你有一个错误,一些随机项目偶尔会变得透明。最好回避所有这些问题。


Loki suggests 可能更好,将weak_ptr 存储到item。如果item 在我们将其设置为透明之前就死了,那很好——我们只是不将其设置为透明。如果我们实际上不需要延长它的生命周期,那就不要:

QTimer::singleShot(1000, [weak_item = std::weak_ptr<QStandardItem>(item)]{
    if (auto item = weak_item.lock()) {
        item->setBackground(Qt::transparent);
    }
});

【讨论】:

  • 更好的选择是让 lambda 获得 std::weak_ptr。然后,当代码决定不再需要该对象时,它的生存时间不会超过所需时间。计时器可以在使用前检查它是否有效。
  • @LokiAstari 我喜欢它。
  • QStandardItem 是一个 Qt 对象这一事实可能是有问题的。例如,QStandardItem 有可能已经拥有一个QStandardItemModel,这可能会排除std::shared_ptr 的使用。但是,我认为除了 OP 之外没有人知道这些细节。
  • @James 对 Qt 一无所知。这只是此类问题的通用答案 - 据我所知,可能存在一种特定于 Qt 的检查项目存在的方法。
  • @Barry 我理解,这不是对您的回答的批评。我只是认为其他人知道需要更多信息才能说这对 OP 或任何处理类似问题的 Qt 用户有用。
【解决方案2】:

似乎没有任何建议对我有用。我尝试了 std::shared_ptr、std::weak_ptr 和 QSharedPointer。似乎该项目被添加到的模型无论如何都会删除该项目?!然而,我最终使用了一个 QStack,我将所有项目指针推入堆栈,一旦恢复或删除,项目就会从堆栈中弹出。由于时间总是相同的,这种方法对我来说非常有效,尽管实施得不是很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2020-02-27
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多