Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std中的分段错误::less<;char>;_C++_Segmentation Fault - Fatal编程技术网

C++ std中的分段错误::less<;char>;

C++ std中的分段错误::less<;char>;,c++,segmentation-fault,C++,Segmentation Fault,我有以下代码(C++0x): const set s_特殊字符={'(','),'{','}',':'}; void nectar_loader::标记化(字符串和行、常量集和特殊_字符) { auto it=line.begin(); const auto not_found=特殊字符。end(); //第一字符特例 if(it!=line.end()&&special_characters.find(*it)!=not_found) it=行。插入(it+1',)+1; while(it!=

我有以下代码(C++0x):

const set s_特殊字符={'(','),'{','}',':'};
void nectar_loader::标记化(字符串和行、常量集和特殊_字符)
{
auto it=line.begin();
const auto not_found=特殊字符。end();
//第一字符特例
if(it!=line.end()&&special_characters.find(*it)!=not_found)
it=行。插入(it+1',)+1;
while(it!=line.end())
{
//检查我们是否在处理一个特殊角色

如果(特殊字符.find(*it)!=not_found)/在第一次取消引用
它之前,您没有检查
它!=line.end()

另一个猜测是
line.append(“”)
有时会使其失效,具体取决于线路的原始容量。

我无法发现错误,我建议使用调试器缓慢迭代,因为您已经识别出问题

一般来说,修改您正在迭代的内容极易失败

我建议使用,更确切地说:与(包括代码示例)结合使用


然后,您可以简单地从第一个字符串构建一个新的
字符串,并从函数返回新字符串。计算的速度应该包括内存分配。

正确,但很难看出这会在rubenvb声称错误所在的点产生segfault。(当然,我们不能绝对肯定这是错误的真实位置。)可能是,但将该检查添加到第一个if:
if(it!=line.end()&&special_characters…
不会修复崩溃
:(
。我还在循环中尝试了第一个if。两种情况下都没有更改。编辑了第一个if。编辑了下一个if(循环中的第一个)不需要检查,正如while条件已经做的那样,但是下一个if需要一种检查无效迭代器的方法。我可以检查
it>=line.begin()吗
或其他什么?它在
find
而不是
*i
中查找故障的原因是
find
通过引用获取其参数。代码只是传递一个指向无效内存的地址,但在尝试从该地址读取之前不会崩溃。传递给
nectar\u loader::tok的字符串是什么在发生SEGFULT时进行nize
(在上面的回溯中不可见)在问题中添加了字符串内容。
insert
也会使迭代器无效。@Gareth:这就是为什么我在调用时使用
return
ed迭代器进行插入的原因。我不能请求追加调用。@rubenvb:哦,是的,你是;对不起。我接受了这个答案,因为它是最有可能的罪魁祸首,尽管在特定的情况下它崩溃了似乎不太可能。我曾想过对
istream
或(
stream\u buf
,应该是子类的)进行子类化,并从更低的级别(子类的
操作符>
)开始工作。在这种情况下,这不是更好的STL解决方案吗?@rubenvb:我对
istream
的本质知之甚少。添加可选行为(如两端完全修剪)似乎更困难。
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;
    }
}
#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)
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;
}