Хранение и доступ к указателю на массив в 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 ответ
Первый вопрос прозвучал так: я попытался запустить его, и он работал без проблем, что дало ожидаемые результаты. Я использовал 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. Я не думаю, что дополнительная пространственная сложность имеет большое значение в этом случае.