c++ 当我尝试在lambda函数中推送向量时,遇到了读访问冲突

lvjbypge  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(150)

抛出异常:读取访问冲突。_My_data为0xFFFFFFFFFFFFE7。
当我运行这段代码时,我得到了这个异常:

b.setOnAction([&](Bullet* b)
    {
        for (int j = 0; j < 10; j++)
        {
            Bullet b1;
            b1.init();
            bullets.push_back(b1);
        }
    }
);

它在添加一个项目符号时有效:

b.setOnAction([&](Bullet* b)
    {
        Bullet b1;
        b1.init();
        bullets.push_back(b1);
    }
);

setOnAction在Bullet类中设置一个std::function变量,该变量在更新函数中调用。
下面是Bullet类:

class Bullet
{
private:
    std::function<void(Bullet*)> mOnAction;

public:
    
    void setOnAction(std::function<void(Bullet*)> func) { mOnAction = func; };

    void init()
    {
        mOnAction = [](Bullet* b) {};
    }

    void update()
    {
        mOnAction(this);
    }
};

bullets是一个充满项目符号对象的向量。
主要功能如下:

int main()
{
    std::vector<Bullet> bullets;

    for (int i = 0; i < 10; i++)
    {
        Bullet b;
        b.init();
        b.setOnAction([&](Bullet* b)
            {
                for (int j = 0; j < 10; j++)
                {
                    Bullet b1;
                    b1.init();
                    bullets.push_back(b1);
                }
            }
        );
        bullets.push_back(b);
    }

    while (true)
    {
        for (int i = bullets.size() - 1; i >= 0; i--)
        {
            Bullet& b = bullets[i];
            b.update();
        }
    }
    return 0;
}
    • 我设法修复了这个问题,方法是将项目符号添加到临时向量,然后从临时向量添加到主项目符号向量**

大概是这样的

**// Temporary vector created besides main bullets vector
std::vector<Bullet> bulletsToAdd;**

b.setOnAction([&](Bullet* b)
            {
                for (int j = 0; j < 10; j++)
                {
                    Bullet b1;
                    b1.init();
                    **//Add to the temp vector
                    bulletsToAdd.push_back(b1);**
                }
            }
        );

while (true)
{
    **// Add everything In the temp vector to the main vector
    for (auto& b : bulletsToAdd)
        bullets.push_back(b);
    // Reset temp vector
    bulletsToAdd.clear();**

    for (int i = bullets.size() - 1; i >= 0; i--)
    {
        Bullet& b = bullets[i];
        b.update();
    }
}
von4xj4u

von4xj4u1#

main中的引用Bullet& b仅在bullets未调整大小时有效,当bullets的容量增加时,所有的对象都会被删除。2因此当你push_back太多的元素时,你调用的mOnAction成员就会失效。由于lambda中捕获的引用存储在std::function中,因此当代码尝试访问bullets引用时会崩溃。
地址清理程序可以在代码出错后尽快崩溃,从而帮助调试这些问题:https://godbolt.org/z/a83Pd9e85

相关问题