Безумный векторный итератор C++

Я заявляю:

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

А потом:

std::vector<SharedPtr> mList;

А также:

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

Возврат mList.size() равен 0, но когда я использую итераторы, он выполняет итерацию по пустому вектору! Вот как я использую итератор:

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

Он выполняет someMethod(), а затем выдает Segmentation Fault. Как итераторы выполняют итерацию в пустом векторе????

Дополнительная информация

Я использую GTK, вот как я передаю основной объект:

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

this является самим ClassB.

И тогда я получаю это так:

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

mList объявляется, как я цитировал, когда я обращаюсь к другому атрибуту, скажем, data->xxx, он работает и все в порядке, проблема возникает только с mList, и этот атрибут не выделяется динамически.

Я проверил адрес памяти *data и this, это один и тот же адрес.


person Tarantula    schedule 28.07.2010    source источник
comment
Вероятно, это не так, вы можете дать нам более полный код?   -  person GManNickG    schedule 29.07.2010
comment
я добавил больше информации   -  person Tarantula    schedule 29.07.2010
comment
Итак, класс A хранит вектор shared_ptrs для экземпляров класса A? Кажется, это не имеет особого смысла.   -  person pmr    schedule 29.07.2010
comment
Извините, я ошибся, я исправлю, я не могу показать исходный код, извините.   -  person Tarantula    schedule 29.07.2010
comment
Теперь это тот же код, но с другими именами переменных.   -  person Tarantula    schedule 29.07.2010
comment
Напишите компилируемый пример, демонстрирующий такое поведение. В противном случае мы должны предположить, что вы неправильно скопировали код.   -  person Martin York    schedule 29.07.2010
comment
Я потрачу больше времени на написание компилируемого примера, чем на исправление проблемы.   -  person Tarantula    schedule 29.07.2010


Ответы (5)


Я решил проблему, объект класса B уничтожался после некоторой области. В любом случае, спасибо, ребята!

person Tarantula    schedule 28.07.2010

Добавьте это утверждение перед циклом for. Если вы активируете его, mList будет поврежден. Например, возможно, содержащий класс также поврежден/мертв/не то, что вы думаете.

assert( mList.size() != 0 || mList.begin() == mList.end() )
person Jon-Eric    schedule 28.07.2010
comment
Я думаю, что он поврежден, но я не могу понять, почему, это простой код! Метод begin() == end() является ложным, а size() равен 0, LOL! Я пытаюсь понять, почему другие атрибуты работают, а не только mList, он не выделяется динамически. - person Tarantula; 29.07.2010
comment
Обычно данные искажаются из-за использования случайных указателей, записи кода в чужую память, двойного удаления динамически выделенных объектов (или других способов передачи недопустимого указателя на delete или delete[]), использования delete вместо delete[] и множества других способов. других тонких ошибок, которые обычно находятся в коде, казалось бы, не связанные с тем, где происходит сбой программы. - person sbi; 29.07.2010

Вы в точности вставили цикл for? Если у вас случайно был бродячий ; в конце вашего цикла for на самом деле может показаться, что он выполняет одну итерацию и делает вызов, как вы видите.

Вы распечатали размер списка непосредственно перед циклом, чтобы убедиться, что он действительно пуст? единственный другой вариант, о котором я могу думать, это то, что список на самом деле не пуст, а содержит один или несколько элементов мусора.

person Mark B    schedule 28.07.2010
comment
Это точно тот же цикл. Я бы распечатал размер списка непосредственно перед выполнением цикла, а размер равен 0. Я не добавляю в него элементы, и если да, то как он говорит size()==0 ? - person Tarantula; 29.07.2010

Возможно, это не ответ в вашем случае, но остерегайтесь ложных конечных точек с запятой в циклах for.

Я часто пишу это и должен дать себе хороший пинок, когда нахожу это...

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

Это может объяснить симптом вызова someMethod, даже когда mList пуст (при условии, что «это» каким-то образом находится в области видимости из другого места).

В противном случае я бы предположил, что mList поврежден до запуска цикла for. Векторы IIRC могут хранить начало, конец и размер отдельно, поэтому, если что-то еще топает по «концу» (например, обнуляет его), тогда начало! = конец, но размер == 0.

Вы всегда можете просто переписать код без итераторов (хорошо, я знаю, что это может просто маскировать проблему, но, эй...)

for (int i=0; i< mList.size(); i++)
  mlist[i]->someMethod();
person Roddy    schedule 28.07.2010
comment
Я проверял это более 5 раз, лол! Это очень странная проблема, я озадачен. - person Tarantula; 29.07.2010

Изменяется ли список во время цикла, возможно, через обратный вызов?

person jyoung    schedule 28.07.2010