By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,264 Members | 1,808 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,264 IT Pros & Developers. It's quick & easy.

Problem storing tvmet vector objects in an stl vector container

P: n/a
The following program demonstrates the problem:

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

typedef tvmet::Vector<double, 3Vector3d;

class Mesh
{
public:
Vector3d* addVertex(const Vector3d& tVertex);
private:
std::vector<Vector3dm_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 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
al**********@gmail.com wrote:
The following program demonstrates the problem:

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

typedef tvmet::Vector<double, 3Vector3d;

class Mesh
{
public:
Vector3d* addVertex(const Vector3d& tVertex);
private:
std::vector<Vector3dm_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
Sep 8 '08 #2

P: n/a
On Sep 8, 9:17*pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
alexjcoll...@gmail.com wrote:
The following program demonstrates the problem:
#include <vector>
#include <iostream>
#include <tvmet/Vector.h>
typedef tvmet::Vector<double, 3Vector3d;
class Mesh
{
public:
* * Vector3d* addVertex(const Vector3d& tVertex);
private:
* * std::vector<Vector3dm_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 '08 #3

P: n/a
al**********@gmail.com 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.
Sep 8 '08 #4

P: n/a
Juha Nieminen wrote:
al**********@gmail.com 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.
The only time pointers/references/iterators to elements are invalidated
is when the elements are removed.
>
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.
....when you push_back or push_front. They are invalidated when
inserting in the middle of the deque, IIRC (if that's at all possible).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 8 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.