gpt4 book ai didi

C++ lambda 表达式 : captured pointer to STL container changing address after pop?

转载 作者:行者123 更新时间:2023-11-27 23:06:51 24 4
gpt4 key购买 nike

我想弄清楚为什么下面的代码会中断。在lambda表达式中调用objects->pop();后,Visual Studio调试时objects的内存地址变为0xfeeefeee。我可以通过在 pop 之前执行 auto p = objects; 来解决这个问题,然后在第二行使用 p 而不是 objects lambda 。但是,我必须在这里遗漏一些基本的东西。

class Obj
{
public:
Obj(stack<shared_ptr<Obj>>* const objects) {
fun = [=] {
objects->pop(); // objects' address changed after this executes
objects->push(shared_ptr<Obj>(new Obj(objects)));
};
}

function<void(void)> fun;
};

int main()
{
stack<shared_ptr<Obj>> objects;
objects.push(shared_ptr<Obj>(new Obj(&objects)));
objects.top().get()->fun();
return 0;
}

最佳答案

您正在观察的是 undefined behavior .

捕获的内存objects调用 objects->pop(); 时释放变量占用一个很好的提示是它更改为的值: 0xFEEEFEEE .这个魔数(Magic Number)表示释放的内存。

让我们分析一下会发生什么。

stack<shared_ptr<Obj>> objects;
objects.push(shared_ptr<Obj>(new Obj(&objects)));

A stackshared_ptr的被创建。推到它上面的是一个新的 Obj实例,其构造函数参数是指向我们的 stack 的指针.

Obj(stack<shared_ptr<Obj>>* const objects) {
fun = [=] {
/* ... */
};
}

A function对象被分配了一个 lambda,它捕获了 objects争论。

objects.top().get()->fun();调用函数对象:

objects->pop(); // objects' address changed after this executes 

objects的栈顶元素指向,是Obj fun 的实例对象所属。通过弹出它,shared_ptr 的唯一(也是最后一个)实例持有对它的引用超出范围并释放它使用的内存。这包括捕获的指向 objects 的指针.在调试版本中 HeapFree将其设置为 0xFEEEFEEE .在发布版本中,任何事情都可能发生。在此之后,您将引用已释放的内存,这是未定义的行为。

关于C++ lambda 表达式 : captured pointer to STL container changing address after pop?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23008198/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com