0

私は宣言する:

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が、同じアドレスです。

4

5 に答える 5

2

私は問題を解決しました。オブジェクトクラスBは、あるスコープの後で破棄されていました。とにかく、みんなありがとう!

于 2010-07-28T22:11:03.123 に答える
1

forループの前にこのアサートを追加します。トリガーすると、mListが破損します。たとえば、おそらく、含まれているクラスも破損している/死んでいる/あなたが思っているものではありません。

assert( mList.size() != 0 || mList.begin() == mList.end() )
于 2010-07-28T21:28:51.243 に答える
0

forループを正確に貼り付けましたか?誤って迷子になった場合; forループの最後では、実際には1回の反復を実行し、表示されているとおりに呼び出しを行うように見えます。

ループの直前にリストサイズを印刷して、実際に空であることを確認しましたか?私が考えることができる他の唯一のオプションは、リストが実際には空ではなく、1つ以上のガベージ要素を含んでいるということです。

于 2010-07-28T21:34:20.017 に答える
0

あなたの場合の答えではないかもしれませんが、forループの末尾のセミコロンに注意してください。

私はよくこれを書き、それを見つけたときに自分自身に良いキックをしなければなりません...

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

mListが空の場合でもsomeMethodが呼び出される症状を説明できます(「it」が他の場所からのスコープ内にあると想定)。

それができない場合、forループが実行される前にmListが破損していると思います。IIRCベクトルは、begin、end、およびsizeを個別に格納する場合があるため、他の何かが「end」を踏みつけた場合(たとえば、ゼロにする)、begin!= endですが、size==0です。

いつでもイテレータのない方法でコードを書き直すことができます(OK、これが問題を覆い隠している可能性があることはわかっていますが、ちょっと...)

for (int i=0; i< mList.size(); i++)
  mlist[i]->someMethod();
于 2010-07-28T21:35:56.800 に答える
0

リストはループ中に、おそらくコールバックを介して変更されていますか?

于 2010-07-28T22:25:18.127 に答える