C++ C++;:读取Lambda捕获的指针时发生访问冲突

C++ C++;:读取Lambda捕获的指针时发生访问冲突,c++,lambda,C++,Lambda,我不会假装我对lambdas很有经验,但对于这个看似简单的问题,我想我需要更深入的了解它到底是如何工作的 我正在外部作用域上实例化一个对象,并使用2个lambda,尝试修改该指针 // Object to be manipulated Object* obj= nullptr; // To be invoked externally in order to construct and initialize obj std::function<void(std::function<v

我不会假装我对lambdas很有经验,但对于这个看似简单的问题,我想我需要更深入的了解它到底是如何工作的

我正在外部作用域上实例化一个对象,并使用2个lambda,尝试修改该指针

// Object to be manipulated
Object* obj= nullptr;

// To be invoked externally in order to construct and initialize obj
std::function<void(std::function<void(const String&)>)> SetObject
    = [&obj](std::function<void(const String&)> func) 
{
    obj= new Object();
    // ... Initialize Values
};

// To be invoked externally to reset and delete obj
std::function<void()> ResetObject
= [&obj]() 
{
    if(obj)
    {
        delete obj;
        obj= nullptr;
    }
};
//要操作的对象
Object*obj=nullptr;
//在外部调用以构造和初始化obj
函数SetObject
=[&obj](标准::函数func)
{
obj=新对象();
//…初始化值
};
//从外部调用以重置和删除obj
函数重置对象
=[&obj]()
{
如果(obj)
{
删除obj;
obj=空PTR;
}
};
在创建对象的新实例之前,执行主代码并首先调用重置方法。假设“主”代码无法访问、读取或修改obj,因此依赖盲复位

预期结果:第一次调用重置表达式时,对obj的检查应返回false,因为obj在外部作用域中被设置为nullptr——不会发生任何事情

实际结果:执行重置时,obj不再指向NULL,检查返回true并调用delete,导致访问冲突

我想知道我试图做的任何事情是否是一个无效的操作,或者我捕获变量的方式是否不正确。我试着通过值捕获指针,将函数设置为可变,绝望地将引用和值捕获结合起来

编辑:在这一点上,正如其他人所指出的,我认为对象的范围是罪魁祸首。我将尝试一种解决方法 记住这一点,然后再报告


虽然我们无法仅从您的示例中判断,但我怀疑
obj
可能是一个局部变量,它在被捕获后超出了范围。解决此问题的一种方法是添加另一个间接级别:

Object** objptr = new Object*();

std::function<void(std::function<void(const String&)>)> SetObject
    = [objptr](std::function<void(const String&)> func) 
{
    *objptr = new Object();
};

std::function<void()> ResetObject
= [objptr]() // Note we are now capturing objptr by value
{
    if(*objptr)
    {
        delete *objptr;
        *objptr = nullptr;
    }
    // Is objptr reused by another call to SetObject?
    // If not, delete it here as well.
    // delete objptr;
};
Object**objptr=新对象*();
函数SetObject
=[objptr](标准::函数func)
{
*objptr=新对象();
};
函数重置对象
=[objptr]()//注意,我们现在按值捕获objptr
{
如果(*objptr)
{
删除*objptr;
*objptr=nullptr;
}
//objptr是否被另一个对SetObject的调用重用?
//如果没有,请在此处删除它。
//删除objptr;
};

调用lambda时,
obj
是否超出范围?是的,我们确实需要知道该声明的范围。请编辑您的问题以包含我很抱歉,我试图尽可能地删除它,因为我不允许共享此代码的上下文。我可以说,我展示的代码(与许多其他lambda表达式一起)在应用程序首次运行时调用的初始化函数中。如果没有足够的信息,请随时删除该问题。是否有充分的理由不能将
obj
包装成一个智能指针,即
std::unique_ptr
?那么,之所以这样做是因为我们按值捕获了objptr?否则,它将与原始示例属于相同的范围问题?