views:

143

answers:

5

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.

+1  A: 

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

assert( mList.size() != 0 || mList.begin() == mList.end() )
Jon-Eric
I think it is corrupted, but I can't figure out why, it's a simple code ! The begin() == end() is false and the size() is 0, LOL ! I'm trying to understand why other attributes work and only mList don't, it isn't allocated dynamically.
Tarantula
Usually, data is corrupted by using stray pointers, code writing to memory it doesn't own, dynamically allocated objects being deleted twice (or other ways of passing an invalid pointer to `delete` or `delete[]`), by using `delete` instead of `delete[]` and a myriad of other subtle bugs which usually are in code seemingly unrelated to where the program crashes.
sbi
A: 

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.

Mark B
It is **exactly** the same loop. I'd print the list size immediately before doing the loop, and the size is 0. I'm not adding elements on it, and if it has, how it says size()==0 ?
Tarantula
A: 

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();
Roddy
I'd checked for this more than 5 times lol ! That's a very weird problem, I'm puzzled..
Tarantula
+1  A: 

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

Tarantula
A: 

Is the list being modified during the loop, maybe through the callback?

jyoung