【问题标题】:Crazy C++ Vector iterator疯狂的 C++ 向量迭代器
【发布时间】:2010-07-28 21:17:58
【问题描述】:

我声明:

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-&gt;xxx 它可以工作并且很好,问题仅出现在 mList 并且此属性不是动态分配的。

我检查了*datathis 的内存地址,它们是同一个地址。

【问题讨论】:

  • 应该不是,能给我们更完整的代码吗?
  • 我添加了更多信息
  • 那么,A 类将 shared_ptrs 的向量保存到 A 类的实例?这似乎没有多大意义。
  • 对不起,我弄错了,我会改正的,我不能显示原始代码对不起。
  • 写一个可编译的例子来展示这种行为。否则我们必须假设他们复制了错误的代码。

标签: c++ iterator segmentation-fault shared-ptr tr1


【解决方案1】:

我已经解决了这个问题,对象类 B 在某个范围后被销毁了。无论如何,谢谢你们!

【讨论】:

    【解决方案2】:

    for 循环之前添加此断言。如果您触发它,mList 已损坏。例如,也许包含的类也已损坏/死/不是您认为的那样。

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

    【讨论】:

    • 我认为它已损坏,但我不知道为什么,这是一个简单的代码! begin() == end() 为假,size() 为 0,哈哈!我试图理解为什么其他属性有效而只有 mList 无效,它不是动态分配的。
    • 通常,由于使用杂散指针、将代码写入不属于它的内存、动态分配的对象被删除两次(或将无效指针传递给 delete 或 @987654325 的其他方式而损坏数据@),通过使用 delete 而不是 delete[] 和无数其他细微的错误,这些错误通常在代码中看似与程序崩溃的位置无关。
    【解决方案3】:

    您是否粘贴了for 循环准确?如果你不小心有一只流浪狗;在您的 for 循环结束时,它实际上似乎会执行一次迭代并按照您所见进行调用。

    您是否直接在循环之前打印出列表大小以确保它实际上是空的?我能想到的唯一其他选择是该列表实际上不是空的,而是包含一个或多个垃圾元素。

    【讨论】:

    • 完全是同一个循环。我会在执行循环之前立即打印列表大小,大小为 0。我没有在上面添加元素,如果有,它怎么说 size()==0 ?
    【解决方案4】:

    在您的情况下可能不是答案,但请注意 for 循环中的虚假尾随分号。

    我经常写这个,当我发现它时不得不给自己一个很好的踢......

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

    它可以解释 someMethod 被调用的症状,即使 mList 为空(假设 'it' 在其他地方的范围内)。

    如果做不到这一点,我猜 mList 在您的 for 循环运行之前已损坏。 IIRC 向量可以分别存储开始、结束和大小,所以如果有其他东西踩在“结束”上(例如将其归零),那么开始!=结束,但大小 == 0。

    您总是可以以无迭代器的方式重写代码(好吧,我知道这可能只是掩盖了问题,但是,嘿......)

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

    【讨论】:

    • 我已经检查了 5 次以上,哈哈!这是一个非常奇怪的问题,我很困惑..
    【解决方案5】:

    列表是否在循环期间被修改,可能是通过回调?

    【讨论】:

      猜你喜欢
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多