微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法在异步Lambda中访问std :: vector *

如何解决无法在异步Lambda中访问std :: vector *

我需要生成一堆随机数,并使用(只是读取)它们来自不同的线程。这是我生成数字的方法

const std::vector<double>* Test::getRandomDoubles(int count)
{
    std::vector<double>* numbers = new std::vector<double>();
    numbers->reserve(count);

    for (int i = 0; i < itemsCount; i++)
    {
        srand((int)std::chrono::high_resolution_clock::Now().time_since_epoch().count());
        numbers->emplace_back(rand() / 1000);
    }
    return numbers;
}

但是我有时会丢失数字:

std::future<void> SomeMethod(const std::vector<double>& numbers)
{
    return std::async( // breakpoint: numbers are available when creating the future.
        std::launch::async,[&]()
        {  // breakpoint: numbers gone. <-
            // Use numbers

如果有帮助,我可以这样调用SomeMethod:

// Just want to run some test for SomeMethod.
std::vector<void> futures;
for(int i = 0; i < 10; i++)
{
   std::vector<double> numbers = *getRandomDoubles(count);
   futures.emplace_back(SomeMethod(numbers));
}
for(int i = 0; i < 10; i++)
{
    futures[i].get();
}

目前,我没有在代码中的任何地方调用delete。

我应该怎么做才能在异步lambda中包含数字?

解决方法

您有责任确保lambda不会超过它通过引用捕获的变量。

如果从函数返回一个lambda,则在调用它时,它已捕获的局部变量早就死了。如果异步运行它并返回future,则会发生同样的事情。

克服此问题的一种方法是通过复制或by move进行捕获。

偶然地,getRandomDoubles()应该调用new并返回一个指针。 C ++不是Java。写

std::vector<double> Test::getRandomDoubles(int count) {
    std::vector<double> numbers;
    ...
    return numbers;
}
,

您捕获的向量是一个副本,而不是您动态分配的副本:

std::vector<double> numbers = *getRandomDoubles(count);

这一行完成后,原始向量将永远作为泄漏的内存消失。将numbers用作参考以避免复制。作为警告,如果您不想将其复制或移动到异步代码中,请确保同步访问该共享可变状态。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。