STL Vector question?

Discussion in 'C++' started by Elzbieta Burnett, Dec 17, 2012.

  1. I have:

    struct point
    {
    double alpha, beta;
    double Force;

    point( double a, double b, double f ) : alpha(a), beta(b), Force(f)
    {}
    };

    struct data
    {
    int dof;
    int XYZ;
    double X, Y, Z;
    int node;
    vector<point> pt;
    };

    map<int, data> AeroDOF;

    I my initialization code I had:

    AeroDOF[ dof[j] ].pt.push_back( point( alpha, beta,
    Force[j] ) );

    I thought that vector '[]' would create an instance of 'point' (like
    map '[]'), call copy constructor and assign newly created entry to
    point( alpha, beta, Force[j] ) in AeroDOF.pt.

    Evidently this isn't true?

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #1
    1. Advertising

  2. Elzbieta Burnett

    jski Guest

    On Dec 17, 2:55 pm, Elzbieta Burnett <>
    wrote:
    > I have:
    >
    > struct point
    > {
    >   double alpha, beta;
    >   double Force;
    >
    >   point( double a, double b, double f ) : alpha(a), beta(b), Force(f)
    > {}
    >
    > };
    >
    > struct data
    > {
    >   int dof;
    >   int XYZ;
    >   double X, Y, Z;
    >   int node;
    >   vector<point> pt;
    >
    > };
    >
    > map<int, data> AeroDOF;
    >
    > I my initialization code I had:
    >
    >         AeroDOF[ dof[j] ].pt.push_back( point( alpha, beta,
    > Force[j] ) );
    >
    > I thought that vector '[]' would create an instance of 'point' (like
    > map '[]'), call copy constructor and assign newly created entry to
    > point( alpha, beta, Force[j] ) in AeroDOF.pt.
    >
    > Evidently this isn't true?
    >
    > <Ella>


    Try:

    struct data
    {
    int dof;
    int XYZ;
    double X, Y, Z;
    int node;
    vector<point *> pt;

    };

    AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    [j] ) );


    Not sure what the answer to your question though.

    ---John
    jski, Dec 17, 2012
    #2
    1. Advertising

  3. Elzbieta Burnett

    Ian Collins Guest

    Elzbieta Burnett wrote:
    > I have:
    >
    > struct point
    > {
    > double alpha, beta;
    > double Force;
    >
    > point( double a, double b, double f ) : alpha(a), beta(b), Force(f)
    > {}
    > };
    >
    > struct data
    > {
    > int dof;
    > int XYZ;
    > double X, Y, Z;
    > int node;
    > vector<point> pt;
    > };
    >
    > map<int, data> AeroDOF;
    >
    > I my initialization code I had:
    >
    > AeroDOF[ dof[j] ].pt.push_back( point( alpha, beta,
    > Force[j] ) );
    >
    > I thought that vector '[]' would create an instance of 'point' (like
    > map '[]'), call copy constructor and assign newly created entry to
    > point( alpha, beta, Force[j] ) in AeroDOF.pt.
    >
    > Evidently this isn't true?


    The evidence has led you the the correct conclusion! The [] operator on
    std::vector does not allocate storage.

    --
    Ian Collins
    Ian Collins, Dec 17, 2012
    #3
  4. On Dec 17, 3:33 pm, Paavo Helde <> wrote:
    > Elzbieta Burnett <> wrote in news:735599ee-
    > :
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > I have:

    >
    > > struct point
    > > {
    > >   double alpha, beta;
    > >   double Force;

    >
    > >   point( double a, double b, double f ) : alpha(a), beta(b), Force(f)
    > > {}
    > > };

    >
    > > struct data
    > > {
    > >   int dof;
    > >   int XYZ;
    > >   double X, Y, Z;
    > >   int node;
    > >   vector<point> pt;
    > > };

    >
    > > map<int, data> AeroDOF;

    >
    > > I my initialization code I had:

    >
    > >         AeroDOF[ dof[j] ].pt.push_back( point( alpha, beta,
    > > Force[j] ) );

    >
    > Your conclusion is right, but it does not follow from the above line. In
    > this line [] is used a lot, but the only case where the container type is
    > known it is a map (AeroDOF). All other variables where [] is applied to
    > are undefined/undeclared (dof, alpha, beta, Force) in your example and so
    > it is not clear if they are vectors, not to speak about how large they
    > are and if they are accessed out of bounds.
    >
    >
    >
    > > I thought that vector '[]' would create an instance of 'point' (like
    > > map '[]'), call copy constructor and assign newly created entry to
    > > point( alpha, beta, Force[j] ) in AeroDOF.pt.

    >
    > On pt you are using push_back() which works more or less exactly as you
    > describe. Your problem is probably elsewhere.
    >
    > Cheers
    > Paavo


    If I use solution proposed by John:

    vector<point *> pt)
    AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    [j] ) );

    this seems to work. Is there problem with this solution?

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #4
  5. On 12/17/2012 4:34 PM, Elzbieta Burnett wrote:
    > On Dec 17, 3:33 pm, Paavo Helde <> wrote:
    >> Elzbieta Burnett <> wrote in news:735599ee-
    >> :
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>
    >>> I have:

    >>
    >>> struct point
    >>> {
    >>> double alpha, beta;
    >>> double Force;

    >>
    >>> point( double a, double b, double f ) : alpha(a), beta(b), Force(f)
    >>> {}
    >>> };

    >>
    >>> struct data
    >>> {
    >>> int dof;
    >>> int XYZ;
    >>> double X, Y, Z;
    >>> int node;
    >>> vector<point> pt;
    >>> };

    >>
    >>> map<int, data> AeroDOF;

    >>
    >>> I my initialization code I had:

    >>
    >>> AeroDOF[ dof[j] ].pt.push_back( point( alpha, beta,
    >>> Force[j] ) );

    >>
    >> Your conclusion is right, but it does not follow from the above line. In
    >> this line [] is used a lot, but the only case where the container type is
    >> known it is a map (AeroDOF). All other variables where [] is applied to
    >> are undefined/undeclared (dof, alpha, beta, Force) in your example and so
    >> it is not clear if they are vectors, not to speak about how large they
    >> are and if they are accessed out of bounds.
    >>
    >>
    >>
    >>> I thought that vector '[]' would create an instance of 'point' (like
    >>> map '[]'), call copy constructor and assign newly created entry to
    >>> point( alpha, beta, Force[j] ) in AeroDOF.pt.

    >>
    >> On pt you are using push_back() which works more or less exactly as you
    >> describe. Your problem is probably elsewhere.
    >>
    >> Cheers
    >> Paavo

    >
    > If I use solution proposed by John:
    >
    > vector<point *> pt)
    > AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    > [j] ) );
    >
    > this seems to work. Is there problem with this solution?


    Only if you consider unnecessary use of pointers a problem. Try

    vector<point> pt; // same as you had before
    ...
    ... pt.push_back(point(alpha...

    I.e. without the pointers and without the 'new'.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 17, 2012
    #5
  6. On Dec 17, 4:47 pm, Paavo Helde <> wrote:
    > Elzbieta Burnett <> wrote innews::
    >
    >
    >
    > > If I use solution proposed by John:

    >
    > > vector<point *> pt)
    > > AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    > > [j] ) );

    >
    > > this seems to work.  Is there problem with this solution?

    >
    > You have not told what problem you have, neither provided a sufficiently
    > complete example demonstrating the problem. Right now I cannot see how
    > using pointers instead of value objects could make anything better here,
    > this would only make working with the data more cumbersome and possibly
    > slower, in addition to creating a risk of memory leaks.
    >
    > Cheers
    > Paavo


    When iterating:

    void AERODATA::Interpolate()
    {
    int i=0;
    ....
    for( map<int, data>::iterator ii = AeroDOF.begin(); ii !=
    AeroDOF.end(); ++ii)
    {

    A.Force = interpextrap( (ii->second).pt[0], //PT1
    (ii->second).pt[3], //PT2
    (ii->second).pt[1], //PT3
    (ii->second).pt[4], //PT4
    alphaNew,
    betaNew );
    i++;

    }
    ....
    }

    I would set breakpoint on interpextrap(...) and examine alpha and beta
    after many calls to AERODATA::Interpolate. These values would be
    completely different from what is read from the file. When I used
    pointers and allocated "points", this problem went away.

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #6
  7. On Dec 17, 5:02 pm, Elzbieta Burnett <>
    wrote:
    > On Dec 17, 4:47 pm, Paavo Helde <> wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > Elzbieta Burnett <> wrote innews::

    >
    > > > If I use solution proposed by John:

    >
    > > > vector<point *> pt)
    > > > AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    > > > [j] ) );

    >
    > > > this seems to work.  Is there problem with this solution?

    >
    > > You have not told what problem you have, neither provided a sufficiently
    > > complete example demonstrating the problem. Right now I cannot see how
    > > using pointers instead of value objects could make anything better here,
    > > this would only make working with the data more cumbersome and possibly
    > > slower, in addition to creating a risk of memory leaks.

    >
    > > Cheers
    > > Paavo

    >
    > When iterating:
    >
    > void AERODATA::Interpolate()
    > {
    >   int i=0;
    > ...
    >   for( map<int, data>::iterator ii = AeroDOF.begin(); ii !=
    > AeroDOF.end(); ++ii)
    >     {
    >
    >       A.Force = interpextrap( (ii->second).pt[0],  //PT1
    >                                  (ii->second).pt[3],  //PT2
    >                                  (ii->second).pt[1],  //PT3
    >                                  (ii->second).pt[4],  //PT4
    >                                  alphaNew,
    >                                  betaNew );
    >       i++;
    >
    >     }
    > ...
    >
    > }
    >
    > I would set breakpoint on interpextrap(...) and examine alpha and beta
    > after many calls to AERODATA::Interpolate. These values would be
    > completely different from what is read from the file.  When I used
    > pointers and allocated "points", this problem went away.
    >
    > <Ella>


    BTW, ONLY time values to AeroDOF[].pt[] are set is when reading from
    data file - one time. They should never change.

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #7
  8. On Dec 17, 5:13 pm, Elzbieta Burnett <>
    wrote:
    > On Dec 17, 5:02 pm, Elzbieta Burnett <>
    > wrote:
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On Dec 17, 4:47 pm, Paavo Helde <> wrote:

    >
    > > > Elzbieta Burnett <> wrote innews::

    >
    > > > > If I use solution proposed by John:

    >
    > > > > vector<point *> pt)
    > > > > AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    > > > > [j] ) );

    >
    > > > > this seems to work.  Is there problem with this solution?

    >
    > > > You have not told what problem you have, neither provided a sufficiently
    > > > complete example demonstrating the problem. Right now I cannot see how
    > > > using pointers instead of value objects could make anything better here,
    > > > this would only make working with the data more cumbersome and possibly
    > > > slower, in addition to creating a risk of memory leaks.

    >
    > > > Cheers
    > > > Paavo

    >
    > > When iterating:

    >
    > > void AERODATA::Interpolate()
    > > {
    > >   int i=0;
    > > ...
    > >   for( map<int, data>::iterator ii = AeroDOF.begin(); ii !=
    > > AeroDOF.end(); ++ii)
    > >     {

    >
    > >       A.Force = interpextrap( (ii->second).pt[0],  //PT1
    > >                                  (ii->second).pt[3],  //PT2
    > >                                  (ii->second).pt[1],  //PT3
    > >                                  (ii->second).pt[4],  //PT4
    > >                                  alphaNew,
    > >                                  betaNew );
    > >       i++;

    >
    > >     }
    > > ...

    >
    > > }

    >
    > > I would set breakpoint on interpextrap(...) and examine alpha and beta
    > > after many calls to AERODATA::Interpolate. These values would be
    > > completely different from what is read from the file.  When I used
    > > pointers and allocated "points", this problem went away.

    >
    > > <Ella>

    >
    > BTW, ONLY time values to AeroDOF[].pt[] are set is when reading from
    > data file - one time. They should never change.
    >
    > <Ella>


    I am using:

    $ g++ --version
    g++ (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #8
  9. On Dec 17, 5:37 pm, Paavo Helde <> wrote:
    > Elzbieta Burnett <> wrote innews::
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > On Dec 17, 4:47 pm, Paavo Helde <> wrote:
    > >> Elzbieta Burnett <> wrote
    > >> innews:da7c9ac3-565e-

    > > :

    >
    > >> > If I use solution proposed by John:

    >
    > >> > vector<point *> pt)
    > >> > AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta,
    > >> > Force [j] ) );

    >
    > >> > this seems to work.  Is there problem with this solution?

    >
    > >> You have not told what problem you have, neither provided a
    > >> sufficiently complete example demonstrating the problem. Right now I
    > >> cannot see how using pointers instead of value objects could make
    > >> anything better here, this would only make working with the data more
    > >> cumbersome and possibly slower, in addition to creating a risk of
    > >> memory leaks.

    >
    > >> Cheers
    > >> Paavo

    >
    > > When iterating:

    >
    > > void AERODATA::Interpolate()
    > > {
    > >   int i=0;
    > > ...
    > >   for( map<int, data>::iterator ii = AeroDOF.begin(); ii
    > >   !AeroDOF.end(); ++ii)
    > >     {

    >
    > >       A.Force = interpextrap( (ii->second).pt[0],  //PT1
    > >                                  (ii->second).pt[3],  //PT2
    > >                                  (ii->second).pt[1],  //PT3
    > >                                  (ii->second).pt[4],  //PT4
    > >                                  alphaNew,
    > >                                  betaNew );
    > >       i++;

    >
    > >     }
    > > ...
    > > }

    >
    > > I would set breakpoint on interpextrap(...) and examine alpha and beta
    > > after many calls to AERODATA::Interpolate. These values would be
    > > completely different from what is read from the file.  When I used
    > > pointers and allocated "points", this problem went away.

    >
    > These symptoms would be explained if you have a custom copy constructor
    > for the point class and which does not do a proper copy (the push_back()
    > operation may copy data around and would use this). Or maybe there is
    > some other error. Why do you check data only "after many calls" and not
    > immediately after reading in the file? Are you sure that the pt vector
    > actually contains at least 5 elements in the above code?
    >
    > For catching unexpected data changes the data breakpoints are great, BTW.
    >
    > hth
    > Paavo


    I have conditional logic that end of interpextrap(...) to catch
    problems. When I saw I had problem, I set conditional breakpoint in
    GDB and examined these values. They should only be -6, 0, or 6. But
    instead they were huge, ridiculous values.

    <Ella>
    Elzbieta Burnett, Dec 17, 2012
    #9
  10. On Dec 17, 5:55 pm, Paavo Helde <> wrote:
    > Elzbieta Burnett <> wrote innews::
    >
    > > I have conditional logic that end of interpextrap(...) to catch
    > > problems. When I saw I had problem, I set conditional breakpoint in
    > > GDB and examined these values.  They should only be -6, 0, or 6.  But
    > > instead they were huge, ridiculous values.

    >
    > Sounds like you are reading uninitialized values. But note that gdb can
    > also report wrong values, especially in optimized code, do not trust the
    > gdb debugger 100%. Make sure to compile your code without optimization for
    > best debugging.
    >
    > As you are on Linux you can also try to run the program with valgrind and
    > see if it spots any memory errors.
    >
    > hth
    > Paavo


    Just to make sure I understand all that's been said;

    Original code:

    struct point
    {
    double alpha, beta;
    double Force;

    point(double a, double b, double f) : alpha(a), beta(b), Force(f) {}

    };

    struct data
    {
    int dof;
    int XYZ;
    double X, Y, Z;
    int node;
    vector<point> pt;

    };

    map<int, data> AeroDOF;

    AeroDOF[dof[j]].pt.push_back(point( alpha, beta,Force[j]));

    This should work?

    "Point" in:

    AeroDOF[dof[j]].pt.push_back(point( alpha, beta,Force[j]));

    is local to initialization routine but STL class (vector) should
    create instance of "point" and copy contents from local "point" to new
    entry in AeroDOF[].pt[] ? Vector values in AeroDOF[].pt[] should not
    go away after call to initialize.

    <Ella>
    Elzbieta Burnett, Dec 18, 2012
    #10
  11. Elzbieta Burnett

    Rui Maciel Guest

    Ian Collins wrote:

    > The evidence has led you the the correct conclusion! The [] operator on
    > std::vector does not allocate storage.


    Is there any assurance made by the standard? From what I've gathered, the
    C++ standard only specifies that std::vector must provide a couple of
    operator[] instances which returns references to members, and that storage
    management is handled automatically by the class.


    Rui Maciel
    Rui Maciel, Dec 18, 2012
    #11
  12. Elzbieta Burnett

    none Guest

    In article <>,
    jski <> wrote:
    >Try:
    >
    > struct data
    > {
    > int dof;
    > int XYZ;
    > double X, Y, Z;
    > int node;
    > vector<point *> pt;
    >
    > };
    >
    >AeroDOF[ dof[j] ].pt.push_back( new point( alpha, beta, Force
    >[j] ) );


    Apart from creating a memory leak, this does nothing useful. Stick to
    using values in the vector unless you have very good reasons not to.

    Yannick
    none, Dec 20, 2012
    #12
  13. Elzbieta Burnett

    Calum Guest

    On Monday, 17 December 2012 19:55:59 UTC, Elzbieta Burnett wrote:
    > I thought that vector '[]' would create an instance of 'point' (like
    >
    > map '[]'), call copy constructor and assign newly created entry to
    >
    > point( alpha, beta, Force[j] ) in AeroDOF.pt.
    >
    >
    >
    > Evidently this isn't true?


    Exactly. std::vector::eek:perator[] never creates new items. However std::map::eek:perator[] behaves differently and does create new items.

    You can use std::vector::at() which performs a bounds check on the vector and will throw an exception if the index is out of range. You must of course catch the exception.

    You could also replace std::vector<point> with std::map<int,point>, so that points are allocated according to your expectations. However this is much less efficient.

    Best to use std::vector::push_back(), resize() or pass the desired size of the vector to the constructor.
    Calum, Dec 20, 2012
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dennis
    Replies:
    1
    Views:
    2,580
    Dennis
    Jun 7, 2004
  2. CD
    Replies:
    2
    Views:
    805
    Victor Bazarov
    Oct 5, 2004
  3. Replies:
    2
    Views:
    414
  4. Replies:
    8
    Views:
    1,914
    Csaba
    Feb 18, 2006
  5. Luca Risolia

    STL map to STL vector

    Luca Risolia, Jan 13, 2014, in forum: C++
    Replies:
    32
    Views:
    362
    Seungbeom Kim
    Jan 18, 2014
Loading...

Share This Page