Friday, April 29, 2011

vector of sequences

I have this data structure Seq which inherits the class vector but has some extra functionalities. Using this data structure Seq I have this predefined data structure:

typedef Seq< vector<int> > MxInt2d;

I want now to have a vector of several components of type MxInt2d; I was thinking about something like:

MxInt2d* loops;

it is just that I think I have to initialize this vector and I do not have a constructor for it. should I write a constructor in order to initialize it ?

thank you in advance. best wishes, madalina

From stackoverflow
  • Don't use pointers, unless you have to. Use vector again:

    vector<MxInt2d> loops;
    

    Right now, the loops container is empty (i.e. there are no matrices inside). If you want it to contain 2 MxInt2d object, you'll either have to insert them or initialize loops differently:

    // loops will contain two empty MxInt2d objects
    vector<MxInt2d> loops(2);
    
    // after the following command,
    // loops will contain 3 MxInt3d objects
    loops.push_back(MxInt2d());
    

    Only after you've populated loops you can start populating its elements.

  • Before getting into your problem-- an observation:

    Are you inheriting the vector ? Deriving vector is not a good idea. All the the standard STL containers, lacks a virtual destructor, and publicly inheriting from classes without virtual destructors is a major C++ no-no.

  • It's not a good idea to inherit from STL containers because they don't have virtual destructors, which can lead to underfined behaviour, if you try to delete a derived pointer through a base pointer (hope I got that right).

  • As it is, your data structure looks complex. By creating a pointer of it, you are making it even more complicated. It's better if you can create an array/vector of MxInt2d instead of making it a pointer.

  • No, not necessarily. std::vector will initialize all elements to 0, so if this is what you need, you won't have to write a custom constructor.

  • Arrays are evil in C++. You can use vector for almost anything that you can use array for. One common problem; that of initialization can be solved. Refer to this discussion how-to-initialize std::vector like 'C' array.

    So, you can use 'vector loops;' without problems.

    HTH,

  • So if on one hand I would have the declaration of the following data structure:

        MxInt2d myEdges_;
    

    which is then initialized. And on the other hand the declaration of my variable loops:

     vector<MxInt2d> loops;
    

    If I want to copy in loops[0] the first 5 elements of myEdges_, I would use the syntax:

    for (int i=0;i<5;i++)
      loops[0].push_back(myEdges_[i]);
    

    The program gets compiled but when I run it I obtain a bus error message.. The same stuff happens if I use the initialization for a second loop:

    for (int i=0;i<5;i++){
     loops[1].push_back(myEdges_[i]);
     }
    

    (sorry for my bad judgement, I am really new with vector) madalina

    avakar : I think you should edit the original question instead of posting the follow-up here (as if it were and answer).
  • You have a couple of problems here.

    One, you should not derive from vector. If you need code that does custom stuff with a vector, you should write a class with your custom stuff that has-a vector, not is-a vector. For example:

    class Seq
    {
    public:
       // assorted constructors
    
    // construct vec_ with zero elements
       Seq() {}; 
    
    // construct vec_ with one element
       Seq(int singleItemToAdd) 
    : vec_(1, singleItemToAdd) {};
    
    // construct vec_ with 'multipleItemsToAdd' elements
       Seq(const int* multipleItemsToAdd, size_t numItemsToAdd) 
    : vec_(multipleItemsToAdd,multipleItemsToAdd+numItemsToAdd) {}; 
    
    
       // assorted custom operations (instead of deriving from vector)
       void customSeqOperation() const
       {
          /// your custom stuff here
          :   :
       }
    private:
       vector<int> vec_;
    };
    

    Next problem, you are saying this code compiles but crashes at runtime:

    vector<MxInt2d> loops;
    for (int i=0;i<5;i++)
      loops[0].push_back(myEdges_[i]);
    

    If this is your essentially compete code, the reason why it crashes is because there is no element at loops[0] -- you haven't added it yet. You need to add an element to loops (which is a vector) before you can access the first one:

    vector<MxInt2d> loops;
    MxInt2d firstElement = getTheElement();
    loops.push_back(firstElement);   
    for (int i=0;i<5;i++)
      loops[0].push_back(myEdges_[i]);
    
  • and how does this function getTheElement should behave, as I see it does not return a pointer to an element of type MxInt2d. I tried with the function returning a pointer but when I call the push_back method with the pointer argument the program does not compile due to the wrong parameter.

    I want to use this function as I added a new data structure and a new variable like: typedef std::vector< edge_t> edge2d_t;

        std::vector< edge2d_t > myEdgesIntersect;
    

    and now I want to create my variable myEdgesIntersect like:

       for (int i=0;i<1;i++){
     edge2d[0][0]=sweepEvents[i][0];
     edge2d[0][1]=sweepEvents[i][1];
     edge2d[1][0]=sweepEvents[i+1][0];
     edge2d[1][1]=sweepEvents[i+1][1];
     std::cout<<edge2d[0][0]<<" "<<edge2d[0][1]<<endl;
     std::cout<<edge2d[1][0]<<" "<<edge2d[1][1]<<endl;
     myEdgesIntersect.push_back(edge2d);
     std::cout<<myEdgesIntersect[i][0][0]<<" "<<myEdgesIntersect[i][0][1]
                <<"     "<<myEdgesIntersect[i][1][0]<<" "<<myEdgesIntersect[i][1][1] 
                <<endl;
    }
    

    but when I run the program the display of the variable myEdgesIntersect is not initialize with the given values of edge2d[..][..] (which during the display are okay). I tried to display the variable myEdgesIntersect before the push_back and I got an bus error, so I think the problem is that the variable is not initialized. I tried to initialize it like:

         edge2d_t edge2d;
         edge2d[0][0]=0;
         edge2d[0][0]=0;
         edge2d[0][0]=0;
         edge2d[0][0]=0;
         edge2d[0][0]=0;
         myEdgesIntersect.push_back(edge2d);
    

    but I got the same error, as actually is the same thing as in the loop. Apparently I do not know how to initialize this quite complicated variable that I really need. If you have any suggestions I would be more than happy.

    thanks in advance, madalina

0 comments:

Post a Comment