【问题标题】:Segmentation fault ignored in XCodeXCode 中忽略了分段错误
【发布时间】:2016-06-01 02:24:09
【问题描述】:

我在基于 Web 的编辑器中遇到此代码的分段错误,但在 XCode 中没有。我对这些错误不是很熟悉,但我查了一下并不能确定问题所在。另一个区别是我在使用 Web 编辑器时删除了 main 方法。有谁知道问题是什么?提前致谢。

#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;

class Lexer
{
public: vector <string> tokenize(vector <string> tokens, string input);
};

vector <string> Lexer::tokenize(vector <string> tokens, string input)
{
    vector <string> consumed;

    if(tokens.size()>50)
    {
        tokens.resize(50);
    }

    //The next section sorts the tokens from largest to smallest

    int swap_count = 0; //this tracks whether the sort needs to happen again

    do
    {
        swap_count = 0; // set the swap count to zero

        for(int i=0; i<tokens.size(); i++) //loop that runs the length of the 'tokens' string
        {
            if(tokens[i].length()<tokens[i+1].length()) // if this token is smaller in length than the next token
            {
                tokens[i].swap(tokens[i+1]); //swap the tokens
                swap_count++; //add one to the swap count
            }
        }
    }
    while(swap_count!=0); //while there are swaps

    //The next section consumes the input string.
    while(input.length()>0)
    {
        int count_tokens_consumed=0;

        for(int i=0; i<tokens.size(); i++) // loop set up to go through the units in the tokens vector
        {
            if(tokens[i]==input.substr(0,tokens[i].length())) //if the current token matches the first part of the input
            {
                consumed.push_back(tokens[i]); //add the token to the consumed vector
                input = input.substr(tokens[i].length()); //remove the token from the front of the input string
                count_tokens_consumed++;
                i=int(tokens.size());
            }
        }

        if (count_tokens_consumed==0)
        {
            input = input.substr(1);//or remove the first character on no match
        }
    }

    return consumed;
}

int main()
{
    Lexer LexerOne;
    vector <string> LexerOne_out = LexerOne.tokenize({"AbCd","dEfG","GhIj"},"abCdEfGhIjAbCdEfGhIj");
    for(vector<string>::iterator i = LexerOne_out.begin(); i != LexerOne_out.end(); ++i)

        cout << *i << " ";
    return 0;
}

【问题讨论】:

  • 未定义行为的结果是未定义的。 (即,在遇到调用未定义行为的代码时,允许 XCode 崩溃,或不崩溃,或窃取您的立体声,或它选择做的任何其他事情)

标签: c++ vector segmentation-fault


【解决方案1】:

是否在一种环境中忽略了分段错误,但在另一种环境中没有被忽略是无关紧要的。
导致分段错误的动作是未定义的行为。


以下代码行:

line 31: tokens[i+1].length()

不是您的令牌的有效索引。
这是因为您从 0 迭代到 tokens.size()
令牌的有效索引范围是从 0 到 tokens.size()-1

【讨论】:

    【解决方案2】:

    if(tokens[i].length() &lt; tokens[i+1].length())

    i+1 索引超出范围。

    现在要回答为什么在一个编译器上运行时会出现一种行为而不是另一种行为,向量越界会导致未定义的行为。任何事情都可能发生,包括“始终正常工作”、“有时工作,其他时候崩溃”、“一直崩溃”、“在您的计算机上工作但在另一台计算机上工作”等。

    如果您希望在超出范围时保持一致的行为,请在访问向量的元素时使用 std::vector::at() 而不是 [ ]

    if(tokens.at(i).length() &lt; tokens.at(i+1).length())

    如果您这样做了,您将在两个编译器上收到std::out_of_range 异常(如果输入相同),而不是随机分段错误。


    如果您编写使用std::vector 的代码,并且您没有在很大程度上使用指针,那么由于超出向量范围会发生很多分段错误问题。所以我通常建议将[ ] 替换为at() 以首先确定任何边界问题。如果有问题,那么他们首先得到清理。清理完毕后,[ ] 将重新引入代码中(因为[ ] 不进行边界检查,它会比对at() 的相同调用运行得更快)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-29
      • 2015-09-01
      • 2018-11-07
      • 2018-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多