SIGSEGV 同时探索 boost::multi_index

SIGSEGV while exploring boost::multi_index

本文关键字:multi index boost 探索 SIGSEGV      更新时间:2023-10-16

我一直在拔头发以找出这个段错误,并决定寻求一些帮助。
我有一个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()时,它显然会崩溃,而不是因为令牌向量。我该如何防止这种情况?我试图在*it++下方添加if(it == myContainer.get<str1>().end()) break;,但没有帮助。
谁能给我一些线索?
谢谢!

您的代码存在许多问题:

  • 如果容器中没有等效于 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);
}

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

确保它们不为 null,分段错误将消失。

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

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