Problem storing tvmet vector objects in an stl vector container

Discussion in 'C++' started by alexjcollins@gmail.com, Sep 8, 2008.

  1. Guest

    The following program demonstrates the problem:

    #include <vector>
    #include <iostream>
    #include <tvmet/Vector.h>

    typedef tvmet::Vector<double, 3> Vector3d;

    class Mesh
    {
    public:
    Vector3d* addVertex(const Vector3d& tVertex);
    private:
    std::vector<Vector3d> m_tVertices;
    };

    Vector3d* Mesh::addVertex(const Vector3d& tVertex)
    { m_tVertices.push_back(tVertex);
    return &m_tVertices.back();
    }

    int main()
    {
    Mesh tMesh;
    Vector3d* pVertex0 = tMesh.addVertex(Vector3d(-1, 1, 1));
    std::cout << "Vertex0: " << (*pVertex0)(0) << ", " << (*pVertex0)
    (1) << ", " << (*pVertex0)(2) << std::endl;
    Vector3d* pVertex1 = tMesh.addVertex(Vector3d( 1, 1, 1));
    std::cout << "Vertex0: " << (*pVertex0)(0) << ", " << (*pVertex0)
    (1) << ", " << (*pVertex0)(2) << std::endl;
    std::cout << "Vertex1: " << (*pVertex1)(0) << ", " << (*pVertex1)
    (1) << ", " << (*pVertex1)(2) << std::endl;
    return 0;
    }

    Which gives the following output:

    Vertex0: -1, 1, 1
    Vertex0: 0, 1, 1
    Vertex1: 1, 1, 1

    Instead of the expected output:

    Vertex0: -1, 1, 1
    Vertex0: -1, 1, 1
    Vertex1: 1, 1, 1

    It is interesting to note that the code behaves correctly if an stl
    list is used instead. I can't work out why this is not working, and it
    seems like such a trivial program! Could anyone explain to me what is
    wrong?
    , Sep 8, 2008
    #1
    1. Advertising

  2. Guest

    On Sep 8, 9:17 pm, Victor Bazarov <> wrote:
    > wrote:
    > > The following program demonstrates the problem:

    >
    > > #include <vector>
    > > #include <iostream>
    > > #include <tvmet/Vector.h>

    >
    > > typedef tvmet::Vector<double, 3> Vector3d;

    >
    > > class Mesh
    > > {
    > > public:
    > >     Vector3d* addVertex(const Vector3d& tVertex);
    > > private:
    > >     std::vector<Vector3d> m_tVertices;
    > > };

    >
    > > Vector3d* Mesh::addVertex(const Vector3d& tVertex)
    > > {   m_tVertices.push_back(tVertex);
    > >     return &m_tVertices.back();
    > > }

    >
    > > int main()
    > > {
    > >     Mesh tMesh;
    > >     Vector3d* pVertex0 = tMesh.addVertex(Vector3d(-1, 1, 1));
    > >     std::cout << "Vertex0: " << (*pVertex0)(0) << ", " << (*pVertex0)
    > > (1) << ", " << (*pVertex0)(2) << std::endl;
    > >     Vector3d* pVertex1 = tMesh.addVertex(Vector3d( 1, 1, 1));
    > >     std::cout << "Vertex0: " << (*pVertex0)(0) << ", " << (*pVertex0)
    > > (1) << ", " << (*pVertex0)(2) << std::endl;
    > >     std::cout << "Vertex1: " << (*pVertex1)(0) << ", " << (*pVertex1)
    > > (1) << ", " << (*pVertex1)(2) << std::endl;
    > >     return 0;
    > > }

    >
    > > Which gives the following output:

    >
    > > Vertex0: -1, 1, 1
    > > Vertex0: 0, 1, 1
    > > Vertex1: 1, 1, 1

    >
    > > Instead of the expected output:

    >
    > > Vertex0: -1, 1, 1
    > > Vertex0: -1, 1, 1
    > > Vertex1: 1, 1, 1

    >
    > > It is interesting to note that the code behaves correctly if an stl
    > > list is used instead. I can't work out why this is not working, and it
    > > seems like such a trivial program! Could anyone explain to me what is
    > > wrong?

    >
    > 'push_back' *is allowed* to invalidate all pointers and iterators to any
    > of the vector's elements.  So, storing 'pVertex0' is probably a bad idea
    > if you intend to grow the vector (matrix).
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Thanks, that makes sense.
    Is push_back allowed to invalidate pointers when using a list?
    , Sep 8, 2008
    #2
    1. Advertising

  3. wrote:
    > Is push_back allowed to invalidate pointers when using a list?


    AFAIK std::list is guaranteed to preserve pointers to existing
    elements valid even if new elements are added.

    If you need random access (and more efficient memory usage) you might
    want to consider using std::deque instead of std::vector. The former
    behaves mostly like std::vector, but pointers are not invalidated.
    Juha Nieminen, Sep 8, 2008
    #3
    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. Maitre Bart
    Replies:
    2
    Views:
    519
    Maitre Bart
    Feb 11, 2004
  2. Replies:
    4
    Views:
    796
    Daniel T.
    Feb 16, 2006
  3. Replies:
    8
    Views:
    1,913
    Csaba
    Feb 18, 2006
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    which STL container do I need for storing a 2D-array?

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Oct 23, 2006, in forum: C++
    Replies:
    20
    Views:
    8,635
  5. dss
    Replies:
    2
    Views:
    386
Loading...

Share This Page