468,504 Members | 1,928 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,504 developers. It's quick & easy.

STL vector problems

Hi,

I've a runtime problem with STL vectors.
Here is the simplified version of the code:

template <class Tclass A {
...
private:
vector<T*myvector;
typename vector<T*>::itarator mIt;
...
};

template <class T>
T* A<T>::function1()
{
typename vector<T*>::iterator it( mIt );
if ( it != myvector.end() )
return function2();

return NULL;
}

template <class T>
T* A<T>::function2()
{
T *temp = *mIt;

if ( mIt != ( --( myvector.end()) ) )
++mIt;
else // line1
mIt = myvector.end(); // line 2

return temp;
}
When the gcc-compiled program is run, I get the error message:

*** glibc detected *** double free or corruption (fasttop): 0x0819b210 ***

When "line1" and "line2" are removed (the else-part of function2),
the program works fine.

What might be the problem?

And another question:
What happens exactly in line "T *temp = *mIt;" ?
I assume that a new variable of type "pointer to T" is defined and
initialized with the address to an element of type T that is stored in
the STL vector. The class T constructor is never invoked here, right? And
why do I actually need to define the type of the pointer (here pointer to
class T)? I mean, the size of the address is always the same. Or is
it important for type checking?

Regards,
Chris

Aug 18 '06 #1
9 4258

"Christian Chrismann" <pl*****@yahoo.dewrote in message
news:44**********************@newsspool3.arcor-online.net...
template <class T>
T* A<T>::function2()
{
T *temp = *mIt;

if ( mIt != ( --( myvector.end()) ) )
++mIt;
else // line1
mIt = myvector.end(); // line 2

return temp;
}
Not an aswer to your question, but...

What is that supposed to do? It looks like either case is identical to me.
If you increment the iterator, and it is equal to one before the end()
iterator, then setting it to end() is identical to incrementing it. So why
not just increment it?

-Howard
Aug 18 '06 #2
Christian Chrismann wrote:
I've a runtime problem with STL vectors.
Here is the simplified version of the code:
Unfortunately it is simplified too much, I think: You left out the main
function, so that compiling the code will not produce a testcase which
reproduces the problem.
template <class Tclass A {
...
private:
vector<T*myvector;
typename vector<T*>::itarator mIt;
...
};

[One other function definition]

template <class T>
T* A<T>::function2()
{
T *temp = *mIt;

if ( mIt != ( --( myvector.end()) ) )
++mIt;
I can not claim that this is the cause of your problem, but you must not
call function2 if mlt compares equal to myvector.end(). Since the message
you see goes away if the next lines, which set mlt to myvector.end(), are
removed, one could guess that this is eventually the case.
else // line1
mIt = myvector.end(); // line 2

return temp;
}
When the gcc-compiled program is run, I get the error message:
[...]
If you use GCC, you have at least two debugging tools at your hand. One is
the "Mudflap"-Option, and the other one is "Libstdc++ debug mode". You may
want to read in GCCs documentation what these do exactly. (Your GCC must be
sufficiently recent for both)

Aug 18 '06 #3
On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:
Hi,

I've a runtime problem with STL vectors. Here is the simplified version of
the code:

template <class Tclass A {
...
private:
vector<T*myvector;
typename vector<T*>::itarator mIt;
...
};

template <class T>
T* A<T>::function1()
{
typename vector<T*>::iterator it( mIt ); if ( it != myvector.end() )
return function2();

return NULL;
}
}
template <class T>
T* A<T>::function2()
{
T *temp = *mIt;

if ( mIt != ( --( myvector.end()) ) )
++mIt;
else // line1
mIt = myvector.end(); // line 2

return temp;
}
}

When the gcc-compiled program is run, I get the error message:

*** glibc detected *** double free or corruption (fasttop): 0x0819b210 ***

When "line1" and "line2" are removed (the else-part of function2), the
program works fine.
Sorry, I made a mistake. Removing lines "line1" and "line2" will not fix
the problem. However, when instead of returning "temp" NULL is returned in
function2, the glibc message does not show up anymore.
Maybe this helps

Aug 19 '06 #4
Christian Chrismann wrote:
Hi,
Hi,
When the gcc-compiled program is run, I get the error message:

*** glibc detected *** double free or corruption (fasttop): 0x0819b210 ***
The problem might be that you use a vector of pointers. So if you copy class
A, not the objects in the vector are copied, but just the pointers. Do you
have a vector<Ain your program ? STL containers make excessive use of the
copy constructor for which the compiler creates a default implementation.
But in your case the default implementation is not correct. The best
solution to this is use vector<Tinstead of vector<T*>.

The default implementation for the copy assignment operator and the copy
constructor don't work for you.

Regards,
Chris
Regards
Thorsten

Aug 19 '06 #5
On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:
Hi,

I've a runtime problem with STL vectors. Here is the simplified version of
the code:
What I just figured out. When the vector is replaced by an STL list, the
problem runs without the "double free or corruption" message. That's
really strange since both an STL vector and a list should work
equivalently.

Aug 20 '06 #6
Christian Chrismann wrote:
On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:
>Hi,

I've a runtime problem with STL vectors. Here is the simplified version
of the code:

What I just figured out. When the vector is replaced by an STL list, the
problem runs without the "double free or corruption" message. That's
really strange since both an STL vector and a list should work
equivalently.
Just a thought: One difference between std::vector and std::list is
invalidation of iterators due to reallocation of the vector when you insert
elements. This does not happen within std::list.
Best

Kai-Uwe Bux
Aug 20 '06 #7
On Sun, 20 Aug 2006 04:20:43 -0400, Kai-Uwe Bux wrote:
Christian Chrismann wrote:
>On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:
>>Hi,

I've a runtime problem with STL vectors. Here is the simplified version
of the code:

What I just figured out. When the vector is replaced by an STL list, the
problem runs without the "double free or corruption" message. That's
really strange since both an STL vector and a list should work
equivalently.

Just a thought: One difference between std::vector and std::list is
invalidation of iterators due to reallocation of the vector when you
insert elements. This does not happen within std::list.
This is very probably the problem :-)
The iterator "mIt" points always to the successor of the element that gets
deleted. Thus, after deleting the current element (and automatic
reallocation of the vector), "mIt" points not more to the old element but
to an element that follows in the vector.

Is there a way to get existing iterators updated when elements in the
vector are inserted/removed so that it always points to the same element?
One possible but also very expensive way is to always update the iterator
with STL's "find" algorithm but this is what I try to avoid.

Regards,
Chris

Aug 20 '06 #8
Christian Chrismann wrote:
On Sun, 20 Aug 2006 04:20:43 -0400, Kai-Uwe Bux wrote:
>Christian Chrismann wrote:
>>On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:

Hi,

I've a runtime problem with STL vectors. Here is the simplified version
of the code:
What I just figured out. When the vector is replaced by an STL list, the
problem runs without the "double free or corruption" message. That's
really strange since both an STL vector and a list should work
equivalently.

Just a thought: One difference between std::vector and std::list is
invalidation of iterators due to reallocation of the vector when you
insert elements. This does not happen within std::list.

This is very probably the problem :-)
The iterator "mIt" points always to the successor of the element that gets
deleted. Thus, after deleting the current element (and automatic
reallocation of the vector), "mIt" points not more to the old element but
to an element that follows in the vector.
The code you posted in the original post does not contain enough detail to
confirm or dispute that theory.

Is there a way to get existing iterators updated when elements in the
vector are inserted/removed so that it always points to the same element?
Not in a clean and general way. One could write a drop-in replacement for
std::vector that does this: the iterator type would consist of a pointer to
the underlying vector and the position of the element within the vector;
each iterator would register with the container upon creation and the
container would keep a list of all iterators pointing into it; when the
container changes due to an insert or delete, it would send a message to
all registered iterators. Those that point after the position of change
will update themselves. I did that once for a text-buffer data structure.
If you do not have that many iterators, the overhead is not that big a
deal. Within a text-buffer, you usually have only a cursor and two markers
for a highlighted block. So that is easy. If you have a whole shadow
data-structure made up of iterators, this approach will become infeasible.

One possible but also very expensive way is to always update the iterator
with STL's "find" algorithm but this is what I try to avoid.
Another possibility is to use std::list. If you have insertions and
deletions at random places, that might be better. After all, that is what
std::list is for.
Best

Kai-Uwe Bux

Aug 20 '06 #9
In article <44***********************@newsspool4.arcor-online.net>,
Christian Chrismann <pl*****@yahoo.dewrote:
On Sun, 20 Aug 2006 04:20:43 -0400, Kai-Uwe Bux wrote:
Christian Chrismann wrote:
On Fri, 18 Aug 2006 19:39:46 +0200, Christian Chrismann wrote:

Hi,

I've a runtime problem with STL vectors. Here is the simplified version
of the code:
What I just figured out. When the vector is replaced by an STL list, the
problem runs without the "double free or corruption" message. That's
really strange since both an STL vector and a list should work
equivalently.
Just a thought: One difference between std::vector and std::list is
invalidation of iterators due to reallocation of the vector when you
insert elements. This does not happen within std::list.

This is very probably the problem :-)
The iterator "mIt" points always to the successor of the element that gets
deleted. Thus, after deleting the current element (and automatic
reallocation of the vector), "mIt" points not more to the old element but
to an element that follows in the vector.
Your answer is contained in your question. If 'mIt' always points to the
successor of the element that gets deleted, then it is the value that
'erase' returns.

mIt = myVec.erase( itToDelete );
Aug 20 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Graeme | last post: by
16 posts views Thread by Honestmath | last post: by
34 posts views Thread by Adam Hartshorne | last post: by
12 posts views Thread by No Such Luck | last post: by
11 posts views Thread by arnuld | last post: by
6 posts views Thread by Andy | last post: by
15 posts views Thread by arnuld | last post: by
reply views Thread by NPC403 | last post: by
3 posts views Thread by gieforce | last post: by
reply views Thread by fmendoza | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.