C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

vector of lists: anyone know how to do this?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
craig
Guest





PostPosted: Sat Jun 17, 2006 9:10 am    Post subject: vector of lists: anyone know how to do this? Reply with quote



I've declared the following as a "vector" of "lists" using STL

vector< list<Edge*> >

I've tried many ways to add objects to this but can't figure out how to
do it. Does anyone have any tips, or references to material that might
explain it?

Any help greatly appreciated.
Back to top
Default User
Guest





PostPosted: Sat Jun 17, 2006 9:10 am    Post subject: Re: vector of lists: anyone know how to do this? Reply with quote



craig wrote:

Quote:
I've declared the following as a "vector" of "lists" using STL

vector< list<Edge*

I've tried many ways to add objects to this but can't figure out how
to do it. Does anyone have any tips, or references to material that
might explain it?

And what is reason you decided to hide your code from us? How can we
figure out what you're doing wrong?




Brian
Back to top
Kirit Sælensminde
Guest





PostPosted: Sat Jun 17, 2006 9:10 am    Post subject: Re: vector of lists: anyone know how to do this? Reply with quote



craig wrote:
Quote:
I've declared the following as a "vector" of "lists" using STL

vector< list<Edge*

I've tried many ways to add objects to this but can't figure out how to
do it. Does anyone have any tips, or references to material that might
explain it?

Any help greatly appreciated.

Why not something like:

Edge *pEdge = NULL;
vector< list< Edge * > > edges( 10 );
edges[ 0 ].push_back( pEdge );


Putting pointers into STL containers is not always a good idea. Make
sure you know what you're doing.

Prefer something like this:

boost::shared_ptr< Edge > pEdge;
vector< list< boost::shared_ptr< Edge > > edges( 10 );
edges[ 0 ].push_back( pEdge );

Your choice of smart pointer depends on context though, although
boost::shared_ptr is for many uses a good one. std::auto_ptr is not
normally a good choice.


Of course including the code that doesn't work and telling us what
you're thinking about might help us to answer better.


K
Back to top
Kirit Sælensminde
Guest





PostPosted: Sun Jun 18, 2006 8:00 am    Post subject: Re: followup (better formating of question) vector of lists Reply with quote

craig wrote:
Quote:
void Graph::addEdge( Vertex &v1, Vertex &v2, int weight )
{
ind = "compute index of Vertex in vertex list"
Edge *e = new Edge (v1, v2, weight );
list <Edge*> lst; <- how to make dynamic ??
adjLists.push_back (lst); <-how to make dynamic??
adjLists[ind].push_back( e );
}

The list is already dynamic, the push_back will add to the end. The
vector is slightly different though. I think you missed the suggestion
of the resize() somewhere.

What you need is (I'm not g'teeing it will compile directly) is
something like:

vector< list< boost::shared_ptr< Edge > > >::size_type ind = /* Your
calc */;
if ( adjLists.size() < ind + 1 ) // Remember it is zero indexed
adjLists.resize( ind + 1 );
adjLists[ ind ].push_back( boost::shared_ptr< Edge >( new Edge( v1, v2,
weight ) ) );

Things to note:
* The if statement checks to see that the vector is big enough _before_
you access the index.
* The use of the smart pointer. Don't get in the habit of using raw
pointers.
* The use of the type vector<>::size_type for the index. Your compiler
vendor has gone to a lot of trouble making sure you won't have any
unexpected overflows etc. when they chose this type. Use it rather than
make your own guess about what is right.
* The vector is zero indexed so index 1 means it must be at least size
2


K
Back to top
Roland Pibinger
Guest





PostPosted: Sun Jun 18, 2006 9:10 am    Post subject: Re: followup (better formating of question) vector of lists Reply with quote

On 17 Jun 2006 20:00:27 <kirit.saelensminde (AT) gmail (DOT) com> wrote:
Quote:
craig wrote:
void Graph::addEdge( Vertex &v1, Vertex &v2, int weight )
{
ind = "compute index of Vertex in vertex list"
Edge *e = new Edge (v1, v2, weight );
list <Edge*> lst; <- how to make dynamic ??
adjLists.push_back (lst); <-how to make dynamic??
adjLists[ind].push_back( e );
}

The list is already dynamic, the push_back will add to the end. The
vector is slightly different though. I think you missed the suggestion
of the resize() somewhere.

What you need is (I'm not g'teeing it will compile directly) is
something like:

vector< list< boost::shared_ptr< Edge > > >::size_type ind = /* Your
calc */;
if ( adjLists.size() < ind + 1 ) // Remember it is zero indexed
adjLists.resize( ind + 1 );
adjLists[ ind ].push_back( boost::shared_ptr< Edge >( new Edge( v1, v2,
weight ) ) );

Why shared_ptrs here? They behave like real pointers but obfuscate the
code, create a dependency to Boost, add the overhead of one
dynamically allocated counter for each Edge object (e.g. 1000 Edges
means 1000 superfluous dynamic allocations), ...
The usual way is to let the destructor do the cleanup.

Quote:
Things to note:
* The if statement checks to see that the vector is big enough _before_
you access the index.
* The use of the smart pointer. Don't get in the habit of using raw
pointers.

On the contrary. Get the habit to avoid "smart" pointers!!

Quote:
* The use of the type vector<>::size_type for the index. Your compiler
vendor has gone to a lot of trouble making sure you won't have any
unexpected overflows etc. when they chose this type. Use it rather than
make your own guess about what is right.
* The vector is zero indexed so index 1 means it must be at least size
2

The code may now look like this:

void Graph::addEdge( Vertex &v1, Vertex &v2, int weight )
{
ind = "compute index of Vertex in vertex list"
Edge *e = new Edge (v1, v2, weight );
if (! (ind < adjLists.size()))
{
adjLists.resize(ind + 1);
}
// push_back dynamically grows the list
adjLists[ind].push_back( e );
}


// destructor
Graph::~Graph()
{
for (vector<list<Edge*> >::size_tye ind = 0;
ind < adjLists.size(); ++ind)
{
for (list<Edge*>::iterator it = adjLists[ind].begin();
it != adjLists[ind].end(); ++it)
{
delete *it;
}
}
}
Back to top
Kirit Sælensminde
Guest





PostPosted: Mon Jun 19, 2006 8:13 am    Post subject: Re: followup (better formating of question) vector of lists Reply with quote

Roland Pibinger wrote:
Quote:
On 17 Jun 2006 20:00:27 <kirit.saelensminde (AT) gmail (DOT) com> wrote:
* The use of the smart pointer. Don't get in the habit of using raw
pointers.

On the contrary. Get the habit to avoid "smart" pointers!!

Hmmm. Not sure that is great advice. Obviously there are places where
raw pointers are appropriate, but once you have the level of skill to
know where they are, then you should know how to use them safely too.

Smart pointers are much safer for use by beginners. I suppose that we
could argue about this until the cows come home. I am somewhat
surprised though. I would have thought recommending smart pointers to
be particularly non-contentious.


K
Back to top
Old Wolf
Guest





PostPosted: Mon Jun 19, 2006 8:30 am    Post subject: Re: vector of lists: anyone know how to do this? Reply with quote

craig wrote:
Quote:
I've declared the following as a "vector" of "lists" using STL

vector< list<Edge*

The elements of a vector must be copyable and assignable.
If you copy a list<Edge*> you will get another list that has
all the same pointers in it. If you then 'delete' the pointers
in one list then the other list will have dangling pointers.

What is your reason for not using a list of Edges?

vector< list<Edge> >
Back to top
Alf P. Steinbach
Guest





PostPosted: Mon Jun 19, 2006 9:10 am    Post subject: Re: followup (better formating of question) vector of lists Reply with quote

* Kirit Sælensminde:
Quote:
Roland Pibinger wrote:
On 17 Jun 2006 20:00:27 <kirit.saelensminde (AT) gmail (DOT) com> wrote:
* The use of the smart pointer. Don't get in the habit of using raw
pointers.
On the contrary. Get the habit to avoid "smart" pointers!!

Hmmm. Not sure that is great advice. Obviously there are places where
raw pointers are appropriate, but once you have the level of skill to
know where they are, then you should know how to use them safely too.

Smart pointers are much safer for use by beginners. I suppose that we
could argue about this until the cows come home. I am somewhat
surprised though. I would have thought recommending smart pointers to
be particularly non-contentious.

If you read this group for a while you'll discover that Roland, for some
unknown reason, takes a very dim view of template-based stuff, including
smart pointers and the Boost library.

Both smart pointers and the Boost library (which contains a number of
smart pointer classes) are highly recommended by most experts, for both
novices and professionals -- although the professionals generally
don't need the recommendation, since most professional C++ programmers
are already using smart pointers and Boost.

The only reason I can think of why Roland recommends against is that
he's stuck with a code base that requires some old compiler that doesn't
handle templates well. Happily that isn't a problem for a novice. Nor
is it a problem in general, but it's an issue one does not control
(except by making sure one isn't made responsible for such old code...).

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Back to top
Guest






PostPosted: Mon Jun 19, 2006 9:10 am    Post subject: Re: vector of lists: anyone know how to do this? Reply with quote

Some of the possible reasons are:
- Each edge object might take lots of memory and if the graph is big,
you might end up using lot of memory
- If you have multiple lists each with a different object, if you
modify one object, the same object in other list does not get updated.
This is because these are two different objects now. It will be hard to
track down bugs that can arise because of this.

Best solution for a situation like this is to use auto/smart pointers
for Edge class. That will allow you to make as many copies of
list<Edge*> and only when the last one is deleted is when your object
will be really deleted.

Atul

Old Wolf wrote:
Quote:
craig wrote:
I've declared the following as a "vector" of "lists" using STL

vector< list<Edge*

The elements of a vector must be copyable and assignable.
If you copy a list<Edge*> you will get another list that has
all the same pointers in it. If you then 'delete' the pointers
in one list then the other list will have dangling pointers.

What is your reason for not using a list of Edges?

vector< list<Edge
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.