for循环期间的动态分配是否会造成内存泄漏?

Will dynamic allocation during a for loop create a memory leak?

本文关键字:内存 泄漏 是否 循环 动态分配 for      更新时间:2023-10-16

我在解决动态分配问题时遇到了一个问题…我有一个累积值的函数reduce,在这种情况下,我正在迭代boost::tuple<double*,double*>。我的问题在这里:

//executes this code in chunks, asynchronously
boost::tuple<double*,double*> res = hpx::parallel::reduce(hpx::parallel::par,
    iter, iter+4,                                                         
    boost::make_tuple<double*,double*>(g,h), [](reference a, reference b) { 
        double *res= new double;  //dynamic allocation! I don't have anyway to delete this memory afterwards
        *res = *boost::get<1>(b) * *boost::get<0>(b);
        return boost::make_tuple<double*,double*>(res,res); });

函数参数为

template< typename ExPolicy, typename Iter, typename T, typename Func>
T reduce(ExPolicy execution_policy, Iter being, Iter end, T && start, Func && op)

我如何避免可能通过动态分配变量创建内存泄漏,但仍然能够用两个指针填充元组?

我宁愿将其视为双精度元组(或其数组);它消除了创建双精度指针元组的所有猜测。

与其认为这是一个潜在的泄漏,不如从所有权的角度来考虑。当你声明一个double类型的局部变量时,栈拥有它,它将被清理。当您创建一个类型为double*的指针时,堆栈拥有指针但不拥有该值,因此该值可能不会被清除。显然,仅仅声明一个double是更简单和容易的,所以当这是一个选项时,更喜欢它。

现在考虑其他潜在的所有者。包含POD类型(如std::tuple<double, double>)的元组将拥有并清除双精度类型,但包含指针类型的元组则不清楚。清理一个std::tuple<double*, double*>不会清理双打。显然,使用双精度元组更简单、更容易,所以如果可以的话,我们更倾向于这样做。

但是,我假设出于各种原因,您必须使用双精度指针的元组

然后考虑底层数据需要的生命周期。你怎么能得到这一生?你能把双精度对象的所有权交给其他在适当的时候会被清理的东西,并把它们的地址存储在元组中指向双精度对象的非所有指针中吗?例如,让您的lambda通过引用捕获外部容器,并将您的双精度对象放入其中,并仅将其地址存储在元组中。

下面是我想表达的意思…但是要小心处理我所展示的向量。我对hpx::parallel::reduce一无所知,但我认为它的并行特性会使这个简化版本完全不安全。两次交错调用push_backback将导致创建错误的元组;对push_back的两个重叠调用很容易损坏向量。更复杂的版本可以同步使用容器。

std::vector<double> v; // XXX: probably unsafe for parallel reduce
boost::tuple<double*,double*> res = hpx::parallel::reduce(hpx::parallel::par,
    iter, iter+4,                                                         
    boost::make_tuple<double*,double*>(g,h), [&v](reference a, reference b) { 
        v.push_back(*boost::get<1>(b) * *boost::get<0>(b));
        return boost::make_tuple<double*,double*>(&v.back(), &v.back()); });