![](/img/trans.png)
[英]Using template call std::less<int>::operator() cause segmentation fault
[英]Segmentation fault in std::less<char>
我有以下代碼(C ++ 0x):
const set<char> s_special_characters = { '(', ')', '{', '}', ':' };
void nectar_loader::tokenize( string &line, const set<char> &special_characters )
{
auto it = line.begin();
const auto not_found = special_characters.end();
// first character special case
if( it != line.end() && special_characters.find( *it ) != not_found )
it = line.insert( it+1, ' ' ) + 1;
while( it != line.end() )
{
// check if we're dealing with a special character
if( special_characters.find(*it) != not_found ) // <----------
{
// ensure a space before
if( *(it-1) != ' ' )
it = line.insert( it, ' ' ) + 1;
// ensure a space after
if( (it+1) != line.end() && *(it+1) != ' ' )
it = line.insert( it+1, ' ');
else
line.append(" ");
}
++it;
}
}
崩潰指向指示的線。 這導致與此gdb回溯的段錯誤:
#0 0x000000000040f043 in std::less<char>::operator() (this=0x622a40, __x=@0x623610, __y=@0x644000)
at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_function.h:230
#1 0x000000000040efa6 in std::_Rb_tree<char, char, std::_Identity<char>, std::less<char>, std::allocator<char> >::_M_lower_bound (this=0x622a40, __x=0x6235f0, __y=0x622a48, __k=@0x644000)
at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_tree.h:1020
#2 0x000000000040e840 in std::_Rb_tree<char, char, std::_Identity<char>, std::less<char>, std::allocator<char> >::find (this=0x622a40, __k=@0x644000)
at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_tree.h:1532
#3 0x000000000040e4fd in std::set<char, std::less<char>, std::allocator<char> >::find (this=0x622a40, __x=@0x644000)
at /usr/lib/gcc/x86_64-unknown-linux-gnu/4.5.2/../../../../include/c++/4.5.2/bits/stl_set.h:589
#4 0x000000000040de51 in ambrosia::nectar_loader::tokenize (this=0x7fffffffe3b0, line=..., special_characters=...)
at ../../ambrosia/Library/Source/Ambrosia/nectar_loader.cpp:146
#5 0x000000000040dbf5 in ambrosia::nectar_loader::fetch_line (this=0x7fffffffe3b0)
at ../../ambrosia/Library/Source/Ambrosia/nectar_loader.cpp:112
#6 0x000000000040dd11 in ambrosia::nectar_loader::fetch_token (this=0x7fffffffe3b0, token=...)
at ../../ambrosia/Library/Source/Ambrosia/nectar_loader.cpp:121
#7 0x000000000040d9c4 in ambrosia::nectar_loader::next_token (this=0x7fffffffe3b0)
at ../../ambrosia/Library/Source/Ambrosia/nectar_loader.cpp:72
#8 0x000000000040e472 in ambrosia::nectar_loader::extract_nectar<std::back_insert_iterator<std::vector<ambrosia::target> > > (this=0x7fffffffe3b0, it=...)
at ../../ambrosia/Library/Source/Ambrosia/nectar_loader.cpp:43
#9 0x000000000040d46d in ambrosia::drink_nectar<std::back_insert_iterator<std::vector<ambrosia::target> > > (filename=..., it=...)
at ../../ambrosia/Library/Source/Ambrosia/nectar.cpp:75
#10 0x00000000004072ae in ambrosia::reader::event (this=0x623770)
我很茫然,不知道我做錯了什么。 任何幫助深表感謝。
編輯:崩潰時的字符串是
sub Ambrosia:lib libAmbrosia
更新:
我根據評論/答案中的建議替換了上述功能。 結果如下。
const string tokenize( const string &line, const set<char> &special_characters )
{
const auto not_found = special_characters.end();
const auto end = line.end();
string result;
if( !line.empty() )
{
// copy first character
result += line[0];
char previous = line[0];
for( auto it = line.begin()+1; it != end; ++it )
{
const char current = *it;
if( special_characters.find(previous) != not_found )
result += ' ';
result += current;
previous = current;
}
}
return result;
}
另一個猜測是line.append(" ")
有時會使it
無效,具體取決於線路的原始容量。
在第一次取消引用it
之前,不要檢查it != line.end()
。
我無法發現錯誤,我建議您使用調試器慢慢迭代,因為您已經確定了問題。
我只是這樣,修改你正在迭代的內容非常容易失敗。
我建議使用Boost Tokenizer ,更准確地說: boost::token_iterator
與boost::char_separator
結合使用(包括代碼示例)。
然后,您可以簡單地從第一個構建一個新string
,並從該函數返回新字符串。 計算速度應該包括內存分配。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.