在 std::map 中存储和访问指向数组的指针

Storing and accessing a pointer to an array in a 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;
}

这会导致段错误。 特别是,每当我尝试访问数组的元素时。

  1. 这有可能奏效吗?
    (我以前从来不需要使用地图,也许我只是由于语法错误而产生错误......)或者换句话说,为什么我不能访问我存储在地图中的内存地址?

  2. 是否有 another/better(/实际工作)方式存储未知数量的数组并给它们一个 "name" 以便以后访问和操作它们?

我知道这里也有人问过类似的问题,但 none 的答案适合我。

第一题回答者: 我尝试 运行 它和它 运行 没有问题,产生了预期的结果。我在上面使用了 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,速度上的差异也很明显。在这种情况下,我认为额外的空间复杂性并不重要。