Stefan Reinhardt February 2016

Storing and accessing a pointer to an array in a std::map

The scenario is: I am writing a framework for a particle simulation application. I need to add various attributes to the particles, which I don't know yet and which are different per Particle. Since an attribute would be accessed and manipulate quite often in a time critical manner, I decided to store them in a plain c array. I would prefer to access the different kind of attributes (like pos, vel, force, etc.) by name. So I decided to use a std::map<const std::string,double*> to store the floating point attributes.

So to my question. I try to store particle attribute values as following

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;
}

Which causes a segfault. In particular, everytime when I try to access elements of the array.

First question: Is there a possibility this can ever work? (I had never the need of using a map before, maybe I simply produce an error due to syntax mistakes...) Or in other words why can't I access the memory address which I stored into the map?

Second question: Would there be another/better(/actually working) way of storing an unknown number of arrays and give them a "name" in order to access and manipulate them later?

I know there were similar questions asked around here but none of the answers worked out for me. Thanks a lot

Answers


Dugi February 2016

First question's awnser: I tried to run it and it run without issues, producing the expected results. I used valgrind on it and it reported no undefined behaviour. Your error must be elsewhere or it was fixed when you changed the bounds of the for cycle.

Second question's awnser: How many variables you have there? std::map is useful only if there is a lot of variables and most of them are unset for most particles. In most cases, it's much more comfortable and far faster to index the properties with an enum, that can be used to address a standard c array. For example:

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

I benchmarked a similar issue and the difference in speed was significant, even if I had to set all unused pointers to nullptr. I don't think that the additional spacial complexity matters much in this case.

Post Status

Asked in February 2016
Viewed 2,711 times
Voted 11
Answered 1 times

Search




Leave an answer