释放函数体内std::function的内存

问题描述 投票:0回答:1

我需要传递一个

std::function
作为要异步执行的
void
指针,因此我在堆上创建了一个
std::function
。删除函数体内的
std::function
对象是否安全?请看下面的例子:

using T = std::function<void()>;

void fun(int data)
{
    T* t = new T([&t, data]()
    {
        //do something
        delete t;
    }

    ExecuteAsync(t);
}
c++ c++17
1个回答
0
投票

迂腐地说,这样做并不安全。 [func.wrap.func]

operator()
仅表示返回
INVOKE<R>(...)
,但不能保证它只包含执行此操作的
return
语句。 假设,它可以像(1)

那样实现
R operator()(ArgTypes... args) {
    R result = INVOKE<R>(f, std​::​forward<ArgTypes>(args)...);
    // read memory in this object
    return result;
}

读取生命周期已结束的对象的内存显然是 UB,所以这会破坏你的代码。 然而,没有标准库这样做,也没有明显的理由说明为什么有人会这样做。

实际上,您所做的事情将会起作用,这与允许使用

delete this
的原因相同。请参阅C++ 中允许“删除此”吗?

但是,如果你必须问自己,从代码风格的角度来看,也许这不是一个好主意。 如果你这样做:

ExecuteAsync(std::move(my_function));

...其中

ExecuteAsync
获得
std::function
的所有权并在执行后销毁它,那么它的正确性和原因会更加明显。 至少,你可以递给
ExecuteAsync
一个
std::unique_ptr


(1) A Returns 段落 仅说明返回值。它没有对实施提出进一步的要求。

© www.soinside.com 2019 - 2024. All rights reserved.