我在基于web的编辑器中遇到了此代码的分段错误,但在XCode中没有。我对这些错误不太熟悉,但我查了一下,无法确定问题所在。另一个区别是,当我使用网络编辑器时,我删除了主方法。有人知道问题出在哪里吗?提前谢谢。
#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;
}
是否在一个环境中忽略了分段错误,而在另一个环境下没有忽略,这无关紧要
导致分段错误的操作是未定义的行为。
以下代码行:
line 31: tokens[i+1].length()
不是令牌的有效索引
这是因为您正在从0迭代到tokens.size()
令牌的有效索引范围为0到tokens.size()-1
。
if(tokens[i].length() < tokens[i+1].length())
i+1
索引越界。
现在,要回答为什么在一个编译器上运行时会出现一种行为而不是另一种行为,使用向量越界会导致未定义的行为。任何事情都可能发生,包括"一直正确工作"、"有时工作,其他时候崩溃"、"一直崩溃","在你的电脑上工作,但不能在另一台电脑上工作"等。
如果您想要在越界时保持一致的行为,请在访问向量的元素时使用std::vector::at()
而不是[ ]
。
if(tokens.at(i).length() < tokens.at(i+1).length())
如果您这样做,那么在两个编译器上都会收到std::out_of_range
异常(如果输入相同),而不是随机分段错误。
如果您编写的代码使用std::vector
,并且您没有在很大程度上使用指针,那么由于超出矢量的范围,会出现许多分割错误问题。所以我通常建议用at()
代替[ ]
,以首先解决任何边界问题。如果有问题,首先要清理。一旦清理干净,[ ]
就会重新引入到代码中(由于[ ]
不进行边界检查,它将比对at()
的相同调用运行得更快)。