简体   繁体   中英

Crazy C++ Vector iterator

I declare:

typedef std::tr1::shared_ptr<ClassA> SharedPtr;

And then:

std::vector<SharedPtr> mList;

And:

typedef std::vector<SharedPtr>::iterator ListIterator;

The return of mList.size() is 0, but when I use iterators, it iterates over the vector which is empty ! This is how I use the iterator:

for(ListIterator it = mList.begin(); it!=mList.end(); it++)
    (*it)->someMethod();

It executes the " someMethod() " and then it throws Segmentation Fault. How iterators is iterating in an empty vector ????

More information

I'm using GTK, so this is how I pass the main object:

g_signal_connect(G_OBJECT(widget), "event", G_CALLBACK(&ClassB::fun), this)

The this is the ClassB itself .

And then I receive it like this:

gboolean ClassB::fun(GtkWidget *widget, GdkEvent *event, ClassB *data)
{
    // The mList is here, and is accessed like this:
    // data->mList
}

The mList is declared as I cited, when I access other attribute, let's say data->xxx it works and it's fine, the problem is occuring only with mList and this attribute is not dynamically allocated.

I've checked the memory address of the *data and of the this , they're the same address.

I've solved the problem, the object class B was being destroyed after some scope. Anyway, thank you guys !

Add this assert before your for loop. If you trigger it, mList is corrupted. Eg, perhaps the containing class is also corrupted/dead/not what you think it is.

assert( mList.size() != 0 || mList.begin() == mList.end() )

Did you paste your for loop exactly ? If you accidentally had a stray ; at the end of your for loop, it would in fact seem to execute one iteration and make the call as you're seeing.

Have you printed out the list size directly before the loop to make sure that it is in fact empty? the only other option I can think of is that the list isn't in fact empty, but contains one or more garbage elements.

Maybe not the answer in your case, but beware of spurious trailing semicolons on for loops.

I often write this and have to give myself a good kicking when I find it...

for(ListIterator it = mList.begin(); it!=mList.end(); it++);
    (*it)->someMethod();

It could account for the symptom of someMethod being called even when mList is empty (assuming 'it' is in scope from elsewhere somehow).

Failing that, I'd guess mList is corrupted before your for loop runs. IIRC vectors may store begin, end AND size separately, so if something else stomps on "end" (eg zeroing it), then begin !=end, but size == 0.

You could always just rewrite the code in an iterator-free way (OK, I know this could just be masking the issue, but, hey...)

for (int i=0; i< mList.size(); i++)
  mlist[i]->someMethod();

列表是否在循环过程中被修改(可能通过回调)?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM