我一直在绞尽脑汁地想找出这个段错误,并决定寻求一些帮助。
我有一个 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 ...

当我打电话时它显然崩溃了 it->str1() 在 while 条件下,不是因为标记向量。我怎样才能防止这种情况发生?我尝试添加 if(it == myContainer.get<str1>().end()) break; 就在下面 *it++, ,但没有帮助。
有人能给我一些线索吗?
谢谢你!

有帮助吗?

解决方案

您的代码存在很多问题:

  • 如果容器中没有相当于的元素,它将崩溃 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() 为空或 token[i] 一片空白。

确保它们不为空,分段错误就会消失。

您可能想要更换 whileif, ,还要注意如果查找是算法查找自 这里, ,如果未找到该项,则返回迭代器作为最后一个元素的迭代器,该迭代器可能有 str1 为空。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top