-2

I cannot find where the vector is reaching beyond itself. I have a feeling it's in my token function but I cannot determine what I'm doing that I'm not allowed to.

I've tried the debugger in Visual Studio but its only confused me more.

Am I hung up in the cons or champ vectors? I think it's stopping during the tokens vector. I've clearly misunderstood something.

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
using namespace std;

// Function for split string for given token

vector<string> split(string str, char token) {
    vector<string> pas;
    string s = "";
    for (int i = 0; i < str.size(); i++) {
        if (str[i] == token) {
            pas.push_back(s);
            s = "";
        }

        else {
            s += str[i];
        }
    }
    pas.push_back(s);

    return pas;
}

// Function for convert time to milliseconds

int convertToMilSeconds(string time) {
    int m = 10 * (time[0] - '0') + time[1] - '0';
    int s = 10 * (time[3] - '0') + time[4] - '0';
    int h = 10 * (time[6] - '0') + time[7] - '0';

    int milSecond = m * 60 * 100 + s * 100 + h;

    return milSecond;
}

// Main method

int main() {
    ifstream inFile;
    string fileName;
    cout << "Enter filename: ";
    cin >> fileName;
    inFile.open(fileName);
    if (inFile.is_open()) {
        string title, temp;
        getline(inFile, title);
        getline(inFile, temp);
        map<int, string> data;
        int n = stoi(temp);
        
        for (int i = 0; i < n; i++) {
            getline(inFile, temp);
            vector<string> tokens = split(temp, ' ');
            if (tokens[2] == "DQ") {
                continue;
            }

            else {
                int milSec = convertToMilSeconds(tokens[2]);
                string name = tokens[1] + ", " + tokens[0] + " " + tokens[2];
                data.insert(pair<int, string>(milSec, name));
            }
        }
        
        vector<int> cons;
        vector<int> champ;
        int val = 1;

        for (map<int, string>::iterator itr = data.begin(); itr != data.end(); itr++) {
            if (val >= 1 && val <= 8) {
                champ.push_back(itr->first);
            }

            if (val >= 9 && val <= 16) {
                cons.push_back(itr->first);
            }
            val++;
        }

        cout << title << " " << "CONSOLATION FINALS" << endl;
        int lane = 1;

        for (int x = 6; x >= 0; x -= 2) {
            map<int, string>::iterator itr = data.find(cons[x]);
            cout << lane << " " << itr->second << endl;
            lane++;
        }

        for (int x = 1; x < 8; x += 2) {
            map<int, string>::iterator itr = data.find(cons[x]);
            cout << lane << " " << itr->second << endl;
            lane++;
        }

        cout << endl << title << " " << "CHAMPIONSHIP FINALS" << endl;
        lane = 1;

        for (int x = 6; x >= 0; x -= 2) {
            map<int, string>::iterator itr = data.find(champ[x]);
            cout << lane << " " << itr->second << endl;
            lane++;
        }

        for (int x = 1; x < 8; x += 2) {
            map<int, string>::iterator itr = data.find(champ[x]);
            cout << lane << " " << itr->second << endl;
            lane++;
        }

    }

    else {
        cout << "File not found" << endl;
    }

    return 0;
}
Sample
  • 11
  • Use tools such as Valgrind or similar. Or depending on compiler its built-in sanitizers (for GCC or Clang add the flag `-fsanitize=undefined` or `-fsanitize=address`). – Some programmer dude Mar 13 '21 at 17:02
  • 4
    With your debugger you can identify where exactly your code fails. – πάντα ῥεῖ Mar 13 '21 at 17:02
  • 1
    Have you run your app on debug mode ? VS should show the line that caused the out of range access and the call stack – limserhane Mar 13 '21 at 17:03
  • 1
    https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems – πάντα ῥεῖ Mar 13 '21 at 17:03
  • ***I've tried the debugger in Visual Studio but its only confused me more*** When it breaks into the Visual Studio Community debugger change the "Stack Frame" combobox on the debugging toolbar to your code. That should show you exactly the line that was executing when you went out of bounds. – drescherjm Mar 13 '21 at 17:10
  • Can you explain what you meant by "I've tried the debugger in Visual Studio but its only confused me more"? What exactly confused you? Because using your debugger to quickly find where the out of bounds access happens is the right answer. – Sam Varshavchik Mar 13 '21 at 17:10
  • I have used the debugger, there are no errors and the program runs fine in debug mode until I get an error that says "Debug Assertion Failed" blah blah blah filepath "Vector Subscript out of range." When I click 'retry' I get a huge log and it does identify a break point at – Sample Mar 13 '21 at 17:12
  • _NODISCARD _Ty& operator[](const size_type _Pos) noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; #if _CONTAINER_DEBUG_LEVEL > 0 _STL_VERIFY( _Pos < static_cast(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range"); #endif // _CONTAINER_DEBUG_LEVEL > 0 return _My_data._Myfirst[_Pos]; } – Sample Mar 13 '21 at 17:13
  • I have no idea what any of that means. Im sorry :X – Sample Mar 13 '21 at 17:13
  • 4
    You need to go up the *call stack* until you reach your own code. – Some programmer dude Mar 13 '21 at 17:14
  • It wont show me an error in my own code. VS Studio opens a vector tab and the error is on line 1502 that I posted above. It's the only error shown as a breakpoint. – Sample Mar 13 '21 at 17:22
  • Now I'm getting unhandled exception at line 58. Thank you everyone for your input. – Sample Mar 13 '21 at 17:25
  • Your problem is likly in the method `convertToMilSeconds` as you do not make sure the string contains enough data before accessing individual elements. I would also suggest posting the data you are reading. In general if you are using vector, string or another container in C++ check that the data exists before accessing it. This is commonly known as defensive programming and is a good habit to develop. – Damian Dixon Mar 13 '21 at 17:26

1 Answers1

0

Ways to find out of range issues:

  1. Run in a debugger. It will probably fail at the right point, but tha tmight depend on the debugger.
  2. Look at the crash file produced. It might take a little effort.
  3. Add range-checks all throughout your code and do output if you're about to violate the range

For the amount of code you have, the third choice wouldn't take you more than 10 minutes.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36