Trouble with vector::iterator

P

Prasad

Hi,

I have been using vector::iterators for a while now. This is the first
time I have encountered this problem.
The vector contains one element.

1. vector<GroupSetTemplate>::iterator gstIt;
2. for(gstIt= this->invariantState.getGroupSetTemplates().begin();
gstIt!=this->invariantState.getGroupSetTemplates().end();gstIt++)
3{
4 cout<<"Gst name"<<(*gstIt).getName()<<endl;
5}

Line 4 throws me segmentation fault.

However if I rewrite the above code using vector::at() it works fine.
GroupSetTemplate element = invariantState.getGroupSetTemplates().at
(0);
cout<<"Gst name"<<element.getName()<<endl;

So I know that there is no problem with the element. Am I missing
something ?
 
A

Andrey Tarasevich

Prasad said:
I have been using vector::iterators for a while now. This is the first
time I have encountered this problem.
The vector contains one element.

1. vector<GroupSetTemplate>::iterator gstIt;
2. for(gstIt= this->invariantState.getGroupSetTemplates().begin();
gstIt!=this->invariantState.getGroupSetTemplates().end();gstIt++)
3{
4 cout<<"Gst name"<<(*gstIt).getName()<<endl;
5}

Line 4 throws me segmentation fault.

However if I rewrite the above code using vector::at() it works fine.
GroupSetTemplate element = invariantState.getGroupSetTemplates().at
(0);
cout<<"Gst name"<<element.getName()<<endl;

So I know that there is no problem with the element. Am I missing
something ?

No, you don't know if there's a problem with the element. In your second
version (with 'at') you create a _copy_ of the vector element, while in
the first version you access the vector element itself. The process of
creating a copy can possibly masquerade the existing problem with the
vector element. Try this

GroupSetTemplate& element =
invariantState.getGroupSetTemplates().at(0);
cout << "Gst name" << element.getName() << endl;

(note the use of reference) and see if it works fine or also throws a
segfault. This would be a better test, compared to your version with a copy.

Otherwise, the code you provided looks fine. The problem must be elsewhere.
 
S

Salt_Peter

Hi,

I have been using vector::iterators for a while now. This is the first
time I have encountered this problem.
The vector contains one element.

1. vector<GroupSetTemplate>::iterator gstIt;
2. for(gstIt= this->invariantState.getGroupSetTemplates().begin();
gstIt!=this->invariantState.getGroupSetTemplates().end();gstIt++)
3{
4 cout<<"Gst name"<<(*gstIt).getName()<<endl;
5}

Line 4 throws me segmentation fault.

However if I rewrite the above code using vector::at() it works fine.
GroupSetTemplate element = invariantState.getGroupSetTemplates().at
(0);
cout<<"Gst name"<<element.getName()<<endl;

So I know that there is no problem with the element. Am I missing
something ?

As already noted, at(0) returns a copy. Your original code involves
iterators. Lets bet member function getGroupSetTemplates() returns a
local variable (hence the seg fault).

The fact that you have a conditional expression in that for loop like
so:

gstIt!=this->invariantState.getGroupSetTemplates().end()

is indicative of poor programming practices.
You could always try a simplified reconstruction of your class
hierarchy and post a short, compilable snippet.
 
J

James Kanze

As already noted, at(0) returns a copy.

Your original code involves iterators. Lets bet member
function getGroupSetTemplates() returns a local variable
(hence the seg fault).

Returns a local variable, or returns a reference to a local
variable. Either could certainly explain his symptoms. (So
could a few other things, but that sounds like a pretty good
guess.)
The fact that you have a conditional expression in that for
loop like so:

is indicative of poor programming practices.

Why? I'd say it was more or less standard practice. In fact, a
for loop without a conditional expression would be an endless
loop. (It's not standard practice to consistently write out the
this->, of course, but maybe this code is in a template, and
invariantState is a member of a dependent base class.)
 
P

Prasad

Returns a local variable, or returns a reference to a local
variable.  Either could certainly explain his symptoms.  (So
could a few other things, but that sounds like a pretty good
guess.)

getGroupSetTemplates() returns a class member. Is that a problem?
 
A

Andrey Tarasevich

Prasad said:
getGroupSetTemplates() returns a class member. Is that a problem?

What does "returns a class member" mean? Does it return a copy of a
class member? Or does it return a reference to a class member? It is a
problem if the former is true.

Did you make a test with 'at' and reference?
 
P

Prasad

What does "returns a class member" mean? Does it return a copy of a
class member? Or does it return a reference to a class member? It is a
problem if the former is true.

Did you make a test with 'at' and reference?

Yes. The test with reference fails too. Any reason why the exact same
calls fail for reference but work for the copy?
Infact a valgrind analysis revealed a problem with string access,
which is in one of the innermost classes.

==32069== Process terminating with default action of signal 11
(SIGSEGV)
==32069== Access not within mapped region at address 0xFFFFFFFC
==32069== at 0x40CCD3A: std::string::string(std::string const&)
(in /usr/lib/libstdc++.so.6.0.9)

Any idea what this error means? AFAIK I am returning any local
references or variables.

~Prasad
 
P

Prasad

What does "returns a class member" mean? Does it return a copy of a
class member? Or does it return a reference to a class member? It is a
problem if the former is true.

I was able to fix the problem.
//Original code
vector<GroupSetTemplates> getGroupSetTemplates()
{
return this->groupSetTemplates;
}

//Fixed code
vector<GroupSetTemplates>& getGroupSetTemplates()
{
return this->groupSetTemplates;
}

My understanding of this is
1. Initially a copy of groupSetTemplates was being returned. I was
getting an error because I was creating an iterator over returned
copy.
2. I am returning a reference of groupSetTemplates. A copy of the
reference is returned which still points to original groupSetTemplate
and hence my code works fine.

Is this understanding correct?
 
P

Prasad

Prasad <[email protected]> kirjutas:







The problem was that you returned two copies of groupSetTemplates, and
you were attempting to iterate from the beginning of the first to the end
of the second.



Basically yes, this is what Andray has tried to talk you.

Terminological note: usually one does not talk about a "copy of a
reference" (though there might be some copying of bits involved in the
CPU level, but this is irrelevant). If the function returns a reference,
it just returns a reference.

Paavo

Thanks Paavo and Andray :)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,150
Members
46,696
Latest member
BarbraOLog

Latest Threads

Top