3

I am getting an out of range exception with my while loop in my code.

I have tried to use an Array instead and the error does not occur with the same loop structure. I am confused why this would happen. I believe that the savedValue <= value[rank.at(current-1)]) statement is what is causing the error.

int suffixArray::size;
std::vector<int> suffixArray::rank;


int main( int argc, char* argv[]) {

    std:: string test = "BANANA$";
    suffixArray testString (test);
    return 0;

}



#include <iostream>
#include <vector>


class suffixArray{
public: static int  size;
public: static std::vector<int> rank;


public: suffixArray(std:: string concatenated ){

    size =(int) concatenated.length();
    std:: cout << size << std:: endl;
    rank.resize(7);


    char *suffixPointers[concatenated.length()];
    int value[concatenated.length()];

    for(int i =0; i <= size-1; i++){
        suffixPointers[i] = &concatenated[i];
        value[i] = (int)concatenated[i];
    }

    std::cout << "[";
    for(int i = 0; i<= size-1; i++){

        std::cout  <<value[i] << " ";
    }
    std::cout << "]"<< std:: endl;


     for(int i = 0; i<=size -1; i++){
        if(i == 0){
          rank.assign(i,i);
        }
        else if(value[i] > value[i-1]){
          rank.assign(i,i);
        }else{
            int current =i;
            int savedValue = value[i];
            int prevSavedRank;
            while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
                prevSavedRank= rank.at(current-1);
                rank.assign(current-1, i);
                rank.assign(current, prevSavedRank);
                current--;
            }
        }
    }



}
};
ImLost
  • 31
  • 3

1 Answers1

2

Adding more logging into your program reveals the problem: you rank.assign(0,0) - the first 0 specifies the new vector length, so this call removes all the elements in the vector (see std::vector::assign docs at cppreference) then call rank.at(0): 0 is not a valid index into an empty vector, so std::out_of_range.

You'll have to rethink your logic.

Program with extra logging:

#include <iostream>
#include <vector>

template <typename T>
struct Vector : std::vector<T>
{
    void assign(size_t count, const T& value)
    {
        std::cout << "assign(count " << count << ", " << value << ")\n";
        std::vector<T>::assign(count, value);
    }

    const T& at(size_t pos) const
    {
        std::cout << "at(" << pos << ")\n";
        return std::vector<T>::at(pos);
    }
};

class suffixArray{
public: static int  size;
public: static Vector<int> rank;


public: suffixArray(std:: string concatenated ){

    size =(int) concatenated.length();
    std:: cout << size << std:: endl;
    rank.resize(7);


    char *suffixPointers[concatenated.length()];
    int value[concatenated.length()];

    for(int i =0; i <= size-1; i++){
        suffixPointers[i] = &concatenated[i];
        value[i] = (int)concatenated[i];
    }

    std::cout << "[";
    for(int i = 0; i<= size-1; i++){

        std::cout  <<value[i] << " ";
    }
    std::cout << "]"<< std:: endl;


     for(int i = 0; i<=size -1; i++){
        if(i == 0){
          rank.assign(i,i);
        }
        else if(value[i] > value[i-1]){
          rank.assign(i,i);
        }else{
            int current =i;
            int savedValue = value[i];
            int prevSavedRank;
            while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
                prevSavedRank= rank.at(current-1);
                rank.assign(current-1, i);
                rank.assign(current, prevSavedRank);
                current--;
            }
        }
    }
}
};

int suffixArray::size;
Vector<int> suffixArray::rank;

int main( int argc, char* argv[]) {
    std:: string test = "BANANA$";
    suffixArray testString (test);
}

Output:

7
[66 65 78 65 78 65 36 ]
assign(count 0, 0)
at(0)
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)

I have tried to use an Array instead and the error does not occur with the same loop structure.

std::array and C-style arrays (T[]) are fixed sized containers, lacking an equivalent of the std::vector::assign you're using to resize your vector, so your program must have been modified quite heavily - not just a clean substitution of an array.

Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
  • @user1118321: you're more gracious than me, at least at this time of the morning ;-). Done. (Oh - it's afternoon here!) – Tony Delroy Feb 08 '19 at 02:30