Хранение и доступ к указателю на массив в std::map

Сценарий таков: я пишу каркас для приложения моделирования частиц. Мне нужно добавить различные атрибуты к частицам, которые я еще не знаю, и которые различаются для каждой частицы. Поскольку к атрибуту можно обращаться и манипулировать довольно часто критичным по времени образом, я решил сохранить его в простом массиве c. Я бы предпочел получить доступ к различным атрибутам (например, pos, vel, force и т. Д.) По имени. Поэтому я решил использовать std::map<const std::string,double*> хранить атрибуты с плавающей точкой.

Итак, на мой вопрос. Я пытаюсь сохранить значения атрибутов частиц следующим образом

double* attr = new double[3 * 10];
std::map<std::string,double*> doubleAttributes3d;
doubleAttributes3d.insert(std::make_pair("pos", attr));

for(int64_t i = 0;i<10;++i)
{
    *(doubleAttributes3d["pos"] + 3 * i) = 1.0;
    *(doubleAttributes3d["pos"] + 3 * i + 1) = 2.0;
    *(doubleAttributes3d["pos"] + 3 * i + 2) = 3.0;
}

double * ptr = doubleAttributes3d["pos"];
for(int64_t i = 0;i<10;++i)
{
    cout << *(ptr + 3 * i) << " ";
    cout << *(ptr + 3 * i + 1) << " ";
    cout << *(ptr + 3 * i + 2) << endl;
}

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

  1. Есть ли вероятность того, что это может сработать?
    (У меня никогда не было необходимости использовать карту раньше, возможно, я просто выдавал ошибку из-за синтаксических ошибок...) Или другими словами, почему я не могу получить доступ к адресу памяти, который я сохранил в карте?

  2. Будет ли другой / лучший (/ реально работающий) способ хранения неизвестного числа массивов и присвоения им "имени" для доступа и манипулирования ими позже?

Я знаю, что здесь задавались похожие вопросы, но ни один из ответов не сработал для меня.

1 ответ

Решение

Первый вопрос прозвучал так: я попытался запустить его, и он работал без проблем, что дало ожидаемые результаты. Я использовал valgrind, и он не сообщил о неопределенном поведении. Ваша ошибка должна быть в другом месте или она была исправлена, когда вы изменили границы цикла for.

Второй вопрос: сколько у вас там переменных? std::map полезен, только если есть много переменных, и большинство из них не установлены для большинства частиц. В большинстве случаев гораздо удобнее и быстрее индексировать свойства с помощью перечисления, которое можно использовать для обращения к стандартному массиву c. Например:

enum pp {
   POS,
   VEL,
   FORCE,
   CHARGE,
   MASS,
   ELECTRON_CONFIGURATION,
   ppMax
 }
 double* particles[1000][ppMax];
 particles[0][POS] = new new double[3 * 10];
 // et cetera

Я сравнил аналогичную проблему, и разница в скорости была значительной, даже если мне пришлось установить все неиспользуемые указатели на nullptr. Я не думаю, что дополнительная пространственная сложность имеет большое значение в этом случае.

Другие вопросы по тегам