Сумасшедший итератор C ++ Vector - PullRequest
0 голосов
/ 29 июля 2010

Я заявляю:

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()», а затем выдает ошибку сегментации.Как итераторы итерируют в пустом векторе ????

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

Я использую 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 они имеют одинаковый адрес.

Ответы [ 5 ]

2 голосов
/ 29 июля 2010

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

1 голос
/ 29 июля 2010

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

assert( mList.size() != 0 || mList.begin() == mList.end() )
0 голосов
/ 29 июля 2010

Изменяется ли список во время цикла, возможно, с помощью обратного вызова?

0 голосов
/ 29 июля 2010

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

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

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

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

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

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

for (int i=0; i< mList.size(); i++)
  mlist[i]->someMethod();
0 голосов
/ 29 июля 2010

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

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

...