0

我一直在拔头发来找出这个段错误,并决定寻求帮助。
我有一个boost::multi_index容器,其中包含(string, string, double)并且在某些时候遇到了段错误。

这是我的代码的简化版本:

#include<iostream>
....

// mySet is a multi_index container which contains <(string str1), (string str2), (double val)>

typedef mySet::index<str1>::type set_by_str1;

...

for(unsigned int i=0; i < token.size(); ++i)
{
    set_by_str1::iteration it = myContainer.get<str1>().find(token[i]);
    while(it->str1() == token[i])
    {
        cout << it->str1() << ", " << it->str2() << ", " << it->val << endl;
    }
    *it++;
}

这段代码看起来工作得很好,但它只有在遇到某个特定的令牌时才会崩溃。(相反地,当它不符合令牌时它永远不会崩溃)。
我猜这是因为it超出了容器本身的范围,但不明白它是如何发生的。

GDB 错误消息显示:

Program received signal SIGSEGV, Segmentation fault.
0x08052e83 in std::string::size (this=0x806e190) at /usr/include/c++/4.4/bits/basic_string.h:629
629       { return _M_rep()->_M_length; }

(gdb) bactrace full
#0  0x08052e83 in std::string::size (this=0x806e190) at /usr/include/c++/4.4/bits/basic_string.h:629
No locals.
#1  0x08050475 in std::operator<< <char, std::char_traits<char>, std::allocator<char> > (__os=..., __str=...)
    at /usr/include/c++/4.4/bits/basic_string.h:2503
No locals.
#2  0x0804e4e0 in MyClass:MyFunction (this=0xbffff534) at src/MyCode.cpp:353 (This is where while condition exists)
... dump of HUGE trace for multi_index ...

当我调用 while 条件时,它显然会崩溃it->str1(),而不是因为令牌向量。我怎样才能防止这种情况?我试图在if(it == myContainer.get<str1>().end()) break;下面添加*it++,但没有帮助。
有人能给我一些线索吗?
谢谢!

4

2 回答 2

0

要么it->str1()为空,要么 token[i]为空。

确保它们不为空,并且分段错误将消失。

您可能希望将 替换为whileif还请注意,如果 find 是从此处查找的算法,如果未找到该项目,它将返回迭代器作为最后一个元素的迭代器,该迭代器可能str1为 null。

另外,您确定要逐个字符地迭代令牌字符串并打印每个令牌字符的每个匹配项,而不是只打印整个令牌字符串的一个匹配项吗?(至少我认为它是一个字符串,因为您的示例代码没有t 定义它)。

于 2012-03-11T06:16:50.200 回答
0

您的代码存在许多问题:

  • 如果容器中没有与 , 等效的元素,它将崩溃token[i],因为find返回end(),这是不可取消引用的。
  • while循环期间it可以到达容器的末尾,并且您将再次无法尊重它。
  • find不会为您提供与键等效的第一个元素token[i],这可能是您想要的;改为使用lower_bound

我建议您将代码更改如下:

pair<set_by_str1::iterator, set_by_str1::iterator> p =
    myContainer.get<str1>().equal_range(token[i]);

while(p.first!=p.second)
{
    cout << p.first->str1() << ", " << p.first->str2() << ", "
         << p.first->val << endl;
    ++(p.first);
}
于 2012-03-11T14:50:32.420 回答