运行-时间检查失败 #0 在 Xout_of_range("invalid string position");在 xstring 中

Run-Time Check Failure #0 at Xout_of_range("invalid string position"); in xstring

我是 C++ 和 Whosebug 的新手,我正在做一个创建有限状态机序列检测器的作业,我被困在几个地方。该程序的目的是从用户那里接受一个二进制序列和一个长度大于该序列的比特流,并为找到的每个比特使用不同的状态在该比特流中搜索该序列。 我已经尝试搜索有关 运行-Time Check Failure #0 的其他问题的答案,但找不到任何特定于我的问题的答案。我仍然不明白为什么会出现这些错误。我在调试器中遇到的具体错误是

  1. 运行-Time Check Failure #0 - ESP 的值没有在函数中正确保存 call.This 将我带到一个名为 xstring 的文件并指向行 Xout_of_range ("无效的字符串位置");
  2. 未处理的异常:std::out_of_range 在第 77 行:if (b.at(i) == s.at(j)) {
  3. 警告:在第二个 try-catch 块中未引用局部变量 bLength。

我知道我不应该 post 整个代码,但我想不出在不意外遗漏相关部分的情况下缩短它的方法。

//C++ program to implement a FSM sequence detector with overlap
#include <iostream>
#include <string>
        
using namespace std;
        
struct statePair { //Defining a state pair structure with state binary string and 
                   //output value                                                                                  
    string state;
    int output=0;
};
        
int main() {
    int sequence, bitStream, count = 0, sLength = 0, bLength = 0,
    i = 0 ,j = 0, *indexes, stateNumber = 0; 
    string s, b, startState, endState, currentState;
    statePair *stateList; //Verify
    while (true) {           /*Taking input of sequence to be detected and 
                             checking if it is valid*/
        cout << "Enter a binary sequence to detect: ";
        cin >> sequence;
        auto s = to_string(sequence); 
        sLength = s.length();
        try {
            if (sLength == 0) {
                throw sequence;
            }
            for (int i = 0; i < sLength; i++) {
                if ((s.at(i) != '0') && (s.at(i) != '1')) { 
                    throw s;
                }
            }
        }
        catch (string s) {
            cout << "Error - enter a binary sequence " << endl;
        }
        catch (int sequence){
            cout << "Error - enter a binary sequence " << endl;
        }
        catch (...) {
            cout << "Error - enter a valid binary sequence"<<endl;
        }
        break;
    }
    stateList = new statePair[sLength+1];  //Verify
    endState = s;
    stateList[sLength].state = endState;
    stateList[sLength].output = 1;
    for (int i = 0; i < sLength; i++) {
        stateList[i].state = s.substr(0, stateNumber);
        stateList[i].output = 0;
    }
    while (true) {       /*Taking input of bitstream in which the sequence 
                          must be detected and checking if it is valid*/
        cout << "Enter a stream of bits: ";
        cin >> bitStream;
        auto b = to_string(bitStream);
        bLength = b.length();
        try {
            for (int i = 0; i < bLength; i++) {
                if ((b.at(i) != '0') && (b.at(i) != '1')) {
                    throw b;
                }
            }
            if (sLength > bLength) {
                throw bLength;    
            }
        }
        catch (string b) {
            cout << "Error - enter a binary sequence " << endl;
        }
        catch (int bLength) { //unreferenced local variable bLength
            cout << "Error - length of bitstream must be greater than sequence being searched" << endl;
        }
        catch (...) {
            cout << "Error - enter a valid binary sequence" << endl;
        break;
        }
    }
    indexes = new int[bLength];
    currentState = startState;
    for (int i = 0; i < bLength; i++) {   //Traversing entire bitstream
        if (b.at(i) == s.at(j)) {     //Bookmarking index of first bit match 
            currentState = stateList[j + 1].state;
            for (int j = 0; j < sLength; j++) {  //Checking for sequence at startIndex
                if (i + j < bLength) {    //Checking if enough bits are left for sequence to be found
                    if (b.substr(i, j) == currentState) {
                        currentState = stateList[j + 1].state;
                        if (currentState == endState) {
                            indexes[count] = i;
                            count++;
                            j = 0;
                            i++;
                        }
                        else {
                            currentState = startState;
                            continue;
                        }
                    }
                    else {
                        j = 0;
                        i++;
                    }
                }
                else {
                    break;
                }
            }
        }
    }
    cout << "The sequence was detected " << count << " times in the given bit stream at the indexes" << indexes << "." << endl;
    cin.get(); //To hold the console window to view output
}

正如评论中指出的那样,您应该学习如何使用调试器或如何在没有调试器的情况下调试程序(例如通过 std::cout)。你是对的,因为你是 C++ 的新手:你的代码是一场灾难。但是因为我们每个人都曾经和你现在处于同样的位置,所以我给你一些提示。

  • 错误 #1:ESP 的值未在函数调用中正确保存。 ESP 是 CPU 上的一个寄存器,用于存储堆栈指针。请参阅::What are the ESP and the EBP registers? and What and where are the stack and heap? 因此,很可能您的程序破坏了堆栈。你看到这个门户的标题了吗,stack-overflow?这与您所取得的成就非常接近。什么时候可能会砸烂他的筹码?大多数情况下,当一个人将 crazy/random/rubbish 索引应用于他的数组时,就会发生这种情况。垃圾进,烂堆出。
  • 错误 #2:未处理的异常:std::out_of_range 在第 77 行:if (b.at(i) == s.at(j)) 现在我必须表扬你使用 .at 而不是通常的 operator[],因为 at 成员函数 在执行操作之前验证它的参数 .如果参数无效(超出范围),此函数将抛出异常。通过这种方式,即使没有调试器,您也知道代码中的错误类型和错误所在行。在这里,i 超出了 b 的范围,或者 j 超出了 s 的范围。
  • 警告 #3 第二个 try-catch 块中未引用局部变量 bLength 。这在这里无关紧要。它只是说您声明了一个变量(作为 catch 参数)但从不使用它。

关于你的程序还有什么可以说的?

  • 您的 main 从 15 个变量的定义开始,这些变量将在以后使用。这是 C-language 风格。在 C++ 中,你应该尽可能晚地定义一个变量/一个 object ,也就是说,在你真正需要它的地方。这将使您避免许多错误。
  • 您将 s 定义为空字符串。但随后使用它就好像它包含有用的数据一样 (endState = s, b.at(i) == s.at(j))。这就是错误 #2 的原因:您将 .at 应用于空字符串。
  • 你定义一些指针只是为了用运算符new来对待它们,也就是说,把它们当作动态分配的数组来对待。除非您是专家,否则不要这样做。使用 std::vector,例如std::vector<statePair> stateList (sLength+1);
  • 您的 while 循环将始终执行一次,因为它们以无条件 break 结束。我明白你想达到什么目的,但你失败了。仔细考虑并更正或完全删除 while 循环。不要使用你不理解的代码。
  • 在您的代码在您的数据上正常运行之前,您不需要像 while 循环中那样的输入检查。

我现在无法给出更多提示,因为您的代码有太多问题需要处理。这是一场雪崩。更正我刚刚指出的那些,然后尝试修复其余的。我相信会有很多。