XCode 中忽略了分段错误

Posted

技术标签:

【中文标题】XCode 中忽略了分段错误【英文标题】:Segmentation fault ignored in XCode 【发布时间】: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 崩溃,或不崩溃,或窃取您的立体声,或它选择做的任何其他事情) 【参考方案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() 的相同调用运行得更快)。

【讨论】:

以上是关于XCode 中忽略了分段错误的主要内容,如果未能解决你的问题,请参考以下文章

分段错误:11 - Xcode 10

由于信号分段错误,命令失败 11 Xcode 9 - iOS 模拟器

Xcode 5.0.1 中未报告分段错误

无法在 Xcode 6.1 中存档正在工作的 6.0.1 Swift 项目/分段错误:11

这段代码一次执行良好,另一次出现分段错误

python跟踪分段错误