c++vectordata-structuresogre3d

Pushing a struct datatype into a vector


My structure is of the type

     struct SegData
      {
          Ogre::Vector3 startPt;
          Ogre::Vector3 endPt;
          float r,g,b;
          float velBeg , velEnd;
      };

    SegData seg;

I have a vector

    std::vector< SegData> temp;

I am trying to push back data of type SegData into my vector temp.

            seg.startPt = Ogre::Vector3(0,0,0);
            seg.endPt = Ogre::Vector3(1,1,1);
            seg.r = 1;
            seg.g = 1;
            seg.b = 1;

            temp.push_back(SegData());
            temp.push_back(seg);

I am unable to push back the element seg in the vector temp and it results in a "Segmentation fault (core dumped)".

Can someone please help me out here. I don't get what is going on.

EDIT

I restarted my laptop and segfault disappeared. But I get weird array sizes. I am posting the code below:

    SegData seg;
    std::vector< SegData> temp;
    zeroVec = Ogre::Vector3(0,0,0);

    posStart = Ogre::Vector3(msg->segments[j].S.position.x,msg->segments[j].S.position.y,
            msg->segments[j].S.position.z);
    posEnd = Ogre::Vector3(msg->segments[j].line.E.position.x,msg->segments[j].line.E.position.y,
            msg->segments[j].line.E.position.z);
//This is a pointer of class rviz::Line that helps plot line
    lineVisual->setPoints(posStart,posEnd);

posLeft = posStart;

    //Loop for pushing in the segData into Vector
    if(posStart!= zeroVec && posEnd!= zeroVec)
    {
        float dist = posStart.distance(posEnd);
        if (dist<1) dist = 1.0;

        if (segVec.size() == 0 || flag<id)
        {
            ROS_INFO_STREAM("INSERTING NEW ELEMENT FOR ID"<<id);  //id is passed on to this function
            segVec.push_back(std::vector<SegData> ());
            flag = id;
        }

        for(float i = 1.0; i<= int(dist); i++)
        {

            posRight.x = posStart.x+ (posEnd.x - posStart.x)*(i/dist);
            posRight.y = posStart.y+ (posEnd.y - posStart.y)*(i/dist);
            posRight.z = 0;


            posLeft = posRight;
            seg.startPt = posLeft;
            seg.endPt = posRight;
            seg.r = 1;
            seg.g = 1;
            seg.b = 1;

            temp.push_back(SegData());

            ROS_INFO_STREAM( "pushing inside temp of size  "<<temp.size());
            temp.push_back(seg);


            ROS_INFO_STREAM( "SIZE OF SEGVEC AT ID: "<<id<<" IS:  "<<segVec[id].size());
        }


        segVec.push_back(temp);

Output:

PROCESS MESSAGE
[ INFO] [1470169803.527734377]: INSERTING NEW ELEMENT FOR ID0
[ INFO] [1470169803.528113954]: pushing inside temp of size  1
[ INFO] [1470169803.528180252]: SIZE OF SEGVEC AT ID: 0 IS:  0
[ INFO] [1470169803.528206653]: pushing inside temp of size  3
[ INFO] [1470169803.528227194]: SIZE OF SEGVEC AT ID: 0 IS:  0
[ INFO] [1470169803.528250226]: pushing inside temp of size  5
[ INFO] [1470169803.528270518]: SIZE OF SEGVEC AT ID: 0 IS:  0
//For the next ID
 PROCESS MESSAGE
[ INFO] [1470169810.320975693]: INSERTING NEW ELEMENT FOR ID1
[ INFO] [1470169810.321037171]: pushing inside temp of size  1
[ INFO] [1470169810.321063642]: SIZE OF SEGVEC AT ID: 1 IS:  5030930206624027720
[ INFO] [1470169810.321093659]: pushing inside temp of size  3
[ INFO] [1470169810.321117828]: SIZE OF SEGVEC AT ID: 1 IS:  5030930206624027720
[ INFO] [1470169810.321141908]: pushing inside temp of size  5

Why is my vector size rapidly expanding?


Solution

  • The big size value is so weird, it's got to be some garbage value, not the real size.

    My first guess is maybe the data type of the library you are using (OGRE) is doing it's own customized memory management, for instance the type Ogre::Vector3 may require some specific memory alignment condition (for performance consideration, or for vectorization purpose etc.). std::vector<SegData> uses the STL's default allocator, and that may not play well with the required alignment condition.

    Just out of curiosity, I searched a little bit and found this post. So basically you could try to pass the STLAllocator<GeneralAllocPolicy> as the second template argument (which specifies the type of customized allocator) to std::vector. This may worth a try, just declare you vector as:

    std::vector<SegData, STLAllocator<SegData,GeneralAllocPolicy> > temp;
    

    (where in the original post, I think they forgot the second SegData template argument). If it does not work, you may need to check the library documentation page (f.e. this one) to see if there should be other allocators or it was some other issue.

    Also note that, this is quite a common issue: many libraries chose to use their own memory management strategy, either due to performance optimization, or simply due to alignment constraint. For instance, the Eigen (a C++ linear algebra library) library's fixed-size vector must be accompanied with it's aligned_allocator for proper alignment (see here if you're interested in some more detail).

    Hope this can help you!