Будет ли динамическое распределение во время цикла for создавать утечку памяти?

У меня проблема с решением проблемы динамического размещения … У меня есть функция reduce который накапливает значения, и в этом случае я перебираю boost::tuple<double*,double*>«S. Моя проблема здесь:

//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)

Как можно избежать утечки памяти, динамически выделяя переменную, но при этом уметь заполнять кортеж двумя указателями?

0

Решение

Я бы предпочел просто рассматривать это как кортеж двойных чисел (или их массив); он удаляет все догадки, которые создал кортеж указателей на двойники.

Вместо того, чтобы думать об этом как о потенциальной утечке, думайте об этом с точки зрения владения. Когда вы объявляете локальную переменную типа double, стек владеет им, и он будет очищен. Когда вы создаете один из типа double*стек владеет указателем, но не владеет значением, поэтому значение не может быть очищено. Очевидно, просто объявив double все проще и проще, поэтому, когда это вариант, предпочтите его.

Теперь рассмотрим других потенциальных владельцев. Кортеж, содержащий типы POD, такие как std::tuple<double, double> будет владеть, а затем очистить двойники, но кортеж, содержащий тип указателя, не ясен. Очистка std::tuple<double*, double*> не будет убирать двойников. Очевидно, что просто использовать кортеж двойных чисел проще и проще, поэтому, если это вариант, предпочтите его.

Но я предполагаю, что по разным причинам вы должны использовать кортеж указателей для удвоений.

Посмотрите, какое время жизни вам нужно для ваших базовых данных. Как вы можете получить эту жизнь? Можете ли вы передать владение двойниками чему-то другому, что будет очищено в нужное время, и сохранить их адреса в не принадлежащих указателю кортежей в двойники? Например, пусть ваш lambda захватит внешний контейнер по ссылке, поместит в него ваши двойники и сохранит только их адреса в кортежах.

Вот попытка показать, что я имею в виду … но будьте осторожны, делая это с вектором, как я это показываю. Я ничего не знаю о hpx::parallel::reduce, но я предполагаю, что его параллельная природа сделает эту упрощенную версию совершенно небезопасной. Два чередованных вызова push_back а также back приведет к созданию неправильных кортежей; два перекрывающихся звонка 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()); });
2

Другие решения


По вопросам рекламы [email protected]