I tried to write a calulator which allows for chaining.
So my firstSet() function handles division an multiplication and the. modifies the vector, until the secondSet() function handle addition and subtraction.I had some bugs with the part where I am erasing vector elements, which is where I suspect the segmentation fault is occurring from.
#include <vector>
#include <iostream>
//Structure:
//Vector 'stream' of data objects , where each element is either a num or operator
//Heirarchy:
//1.* & /
//2.+ & -
//expected input : Spaced integers with operators and a semicolon to end the input statement.
//for ex:
//3+2;
//5/6;
struct Data
{
char type;
int val;
char op;
Data(char x , char y)
: type(x) , op(y){}
Data(char x , int y) : type(x) , val(y){}
};
void firstSet(std::vector<Data> & v) // / & *
{
int temp;
for (auto i = v.begin(); i != v.end()-1 ; ++i)
{
if ((*i).type == 'o' && ((*i).op == '/' || (*i).op == '*'))
{
if ((*i).op == '/')
{
temp = (*(i-1)).val / (*(i+1)).val;
}
if ((*i).op == '*')
{
temp = (*(i-1)).val * (*(i+1)).val;
}
(*(i-1)).val = temp; // change lhs
v.erase(i); //delete operator
v.erase(i); //delete rhs
}
}
}
void secondSet(std::vector<Data> & v) // + & -
{
int temp;
for (auto i = v.begin(); i != v.end() ; ++i)
{
if ((*i).type == 'o' && ((*i).op == '+' || (*i).op == '-') )
{
if ((*i).op == '+')
{
temp = (*(i-1)).val + (*(i+1)).val;
}
if ((*i).op == '-')
{
temp = (*(i-1)).val - (*(i+1)).val;
}
(*(i-1)).val = temp;
v.erase(i);
v.erase(i);
}
}
}
int main()
{
std::vector<Data> v;
char T;
std::cin >>T;
while (T != ';')
{
if (T == '/' || T == '*' || T == '+' || T == '-')
{
v.push_back(Data{'o' , T});
}
if (T >= '0' && T <= '9')
{
std::cin.putback(T);
int x;
std::cin >> x;
v.push_back(Data{'n' , x});
}
std::cin >> T;
}
firstSet(v);
secondSet(v);
std::cout << v[0].val;
}
p.s any comments on code readability and neatness in general would be helpful as I want the code to be 'clean'.
Using i after v.erase(i) is invalid, because calling erase [...]invalidates iterators and references at or after the point of the erase, including the end() iterator.[...]
So the second v.erase(i) is wrong, but also continuing the loop using ++i is invalid, and would result in undefined behavior.
You need to replace i with a valid iterator after your erase called. E.g. using:
i = v.erase(i);
But doing so will result in skipping each element after the erased one, so you need to change the logic of your loop.
But there are other parts that are invalid:
(*(i-1)).val = temp; will be invalid if i==v.begin()
(*(i+1)).val will be invalid if (i+1)==v.end()
So you need to think over the complete logic of your code in general.
Related
I made a function infixToPostfix() which converts an infix expression to a postfix expression. But my program generates no output on running. Please point out the errors in my program.
Code:
#include <iostream>
#include <cstring>
#include <stack>
#include <cstdlib>
using namespace std;
int isOperator(char x)
{
return (x == '-' || x == '+' || x == '/' || x == '*');
}
int precedenceOfOperators(char x)
{
if (x == '+' || x == '-')
{
return 1;
}
else if (x == '/' || x == '*')
{
return 2;
}
return 0;
}
char *infixToPostfix(char infix[])
{
int i = 0, j = 0;
stack<char> lobby;
char *postfix = (char *)malloc((strlen(infix + 1)) * sizeof(char));
while (infix[i] != '\0')
{
if (!isOperator(infix[i]))
{
postfix[j] = infix[i];
i++;
j++;
}
else
{
if (!lobby.empty())
{
if (precedenceOfOperators(infix[i]) > precedenceOfOperators(lobby.top()))
{
lobby.push(infix[i]);
}
else
{
postfix[j] = lobby.top();
lobby.pop();
j++;
}
}
else if (lobby.empty())
{
lobby.push(infix[i]);
}
}
}
while (!lobby.empty())
{
postfix[j] = lobby.top();
lobby.pop();
j++;
}
return postfix;
}
Implementation:
int main()
{
char infix[] = {'a', '-', 'b', '+', 'c', '*', 'd'};
char *postfix = infixToPostfix(infix);
for (int j = 0; postfix[j] != '\0'; j++)
{
cout << postfix[j];
}
return 0;
}
Logic:
I created a character pointer variable that will hold our postfix expression. Now, we iterate over our infix expression. If we receive an operand, we concatenate it to the postfix variable. Else if we encounter an operator, we proceed with the following steps:
Keep in account the operator and its relative precedence ('/' and '*' have more precedence than '+' and '-').
If either the stack is empty or its topmost operator has lower relative precedence, push this operator-precedence pair inside the stack 'lobby'.
Else, keep popping operators from the stack 'lobby' and concatenate them to the postfix expression until the topmost operator becomes weaker in precedence relative to the current operator.
If you reach the EOE, pop every element from the stack 'lobby', if there is any, and concatenate them as well to the postfix expression.
Your code is exceeding the time limit because it is stuck in the infinite loop. You have not updated the i variable- which is the index of the infix array in the else part of the loop i.e when infix[i] is an operator. i.e. in this part of the code
else
{
if (!lobby.empty())
{
if (precedenceOfOperators(infix[i]) > precedenceOfOperators(lobby.top()))
{
lobby.push(infix[i]);
}
else
{
postfix[j] = lobby.top();
lobby.pop();
j++;
}
}
else if (lobby.empty())
{
lobby.push(infix[i]);
}
}
Here is the updated code which is giving perfect output. ( I have made some minor changes as per my convenience, you can keep the code the same and add the i++ in the else part)
#include <iostream>
#include <cstring>
#include <stack>
#include <cstdlib>
using namespace std;
int isOperator(char x)
{
return (x == '-' || x == '+' || x == '/' || x == '*');
}
int precedenceOfOperators(char x)
{
if (x == '+' || x == '-')
{
return 1;
}
else if (x == '/' || x == '*')
{
return 2;
}
return 0;
}
string infixToPostfix(char infix[])
{
int i = 0, j = 0;
if(sizeof(infix)==0)
{
return "";
}
int n=sizeof(infix)/sizeof(infix[0]);
stack<char> lobby;
string postfix = "";
while (i < n)
{
if (!isOperator(infix[i]))
{ postfix=postfix+infix[i];
i++;
j++;
}
else
{
if (!lobby.empty())
{
if (precedenceOfOperators(infix[i]) > precedenceOfOperators(lobby.top()))
{
lobby.push(infix[i]);
}
else
{
postfix = postfix+lobby.top();
lobby.pop();
j++;
}
}
else if (lobby.empty())
{
lobby.push(infix[i]);
}
i++;
}
}
while (lobby.empty()==false)
{
postfix = postfix+lobby.top();
lobby.pop();
j++;
}
return postfix;
}
int main()
{
char infix[] = {'a', '-', 'b', '+', 'c', '*', 'd'};
string postfix = infixToPostfix(infix);
for (int j = 0; j < postfix.size() ; j++)
{
cout << postfix[j];
}
return 0;
}
After going through my code again I found some other logical errors too. I have found a better way and have restructured the else part of while loop of function infixToPostfix().
And rather than taking the Infix expression as a character array, I have taken it as a string and similarly Postfix expression is also considered as a string.
Updated infixToPostfix():
string infixToPostfix(string infix)
{
int i = 0;
stack<char> lobby;
string postfix;
if (infix.size() == 0)
{
return "";
}
while (infix[i] != '\0')
{
if (!isOperator(infix[i]))
{
postfix = postfix + infix[i];
i++;
}
else
{
while (!lobby.empty() && precedenceOperator(infix[i]) <= precedenceOperator(lobby.top()))
{
postfix += lobby.top();
lobby.pop();
}
lobby.push(infix[i]);
i++;
}
}
while (!lobby.empty())
{
postfix = postfix + lobby.top();
lobby.pop();
}
return postfix;
}
And as mentioned in other answers, i variable should also be updated in the else part of the while loop.
I am just kind of starting to code and this was in a book that I am using to learn C++. It should be working straight from the book and I can't figure out how to fix it.
I think the problem might be because it lacks the constant operator but if you add it in doesn't that prevent you from modifying the value?
The book is by Drozdek titles Data Structures and Algorithms in C++ if you need that. Thanks for the help!
#include <iostream>
#include <cctype>
#include <cstdlib>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
class Variable {
public:
char id;
int exp;
Variable() { // required by <vector>;
}
Variable(char c, int i) {
id = c; exp = i;
}
bool operator== (const Variable& v) const {
return id == v.id && exp == v.exp;
}
bool operator< (const Variable& v) const { // used by sort();
return id < v.id;
}
};
class Term {
public:
Term() {
coeff = 0;
}
int coeff;
vector<Variable> vars;
bool operator== (const Term&) const;
bool operator!= (const Term& term) const { // required by <list>
return !(*this == term);
}
bool operator< (const Term&) const;
bool operator> (const Term& term) const { // required by <list>
return *this != term && (*this < term);
}
int min(int n, int m) const {
return (n < m) ? n : m;
}
};
class Polynomial {
public:
Polynomial() {
}
Polynomial operator+ (Polynomial&);
void error(char *s) {
cerr << s << endl; exit(1);
}
private:
list<Term> terms;
friend istream& operator>> (istream& in, Polynomial& polyn) {
char ch, sign, coeffUsed, id;
int exp;
Term term;
in >> ch;
while (true) {
coeffUsed = 0;
if (!isalnum(ch) && ch != ';' && ch != '-' && ch != '+')
polyn.error("Wrong character entered2");
sign = 1;
while (ch == '-' || ch == '+') { // first get sign(s) of Term
if (ch == '-')
sign *= -1;
ch = in.get();
if (isspace(ch))
in >> ch;
}
if (isdigit(ch)) { // and then its coefficient;
in.putback(ch);
in >> term.coeff;
ch = in.get();
term.coeff *= sign;
coeffUsed = 1;
}
else term.coeff = sign;
int i;
for (int i = 0; isalnum(ch); i++) { // process this term:
id = ch; // get a variable name
ch = in.get();
if (isdigit(ch)) { // and an exponent (if any);
in.putback(ch);
in >> exp >> ch;
}
else exp = 1;
term.vars.push_back(Variable(id,exp));
}
polyn.terms.push_back(term); // and include it in the linked list;
term.vars.resize(0);
if (isspace(ch))
in >> ch;
if (ch == ';') // finish if a semicolon is entered;
if (coeffUsed || i > 0)
break;
else polyn.error("Term is missing"); // e.g., 2x - ; or just ';'
else if (ch != '-' && ch != '+') // e.g., 2x 4y;
polyn.error("wrong character entered");
}
for (list<Term>::iterator it = polyn.terms.begin(); it != polyn.terms.end(); it++)
if (it->vars.size() > 1)
sort(it->vars.begin(),it->vars.end());
return in;
}
friend ostream& operator<< (ostream& out, const Polynomial& polyn) {
int afterFirstTerm = 0, i;
for (list<Term>::const_iterator pol = polyn.terms.begin(); pol != polyn.terms.end(); pol++) {
out.put(' ');
if (pol->coeff < 0) // put '-' before polynomial
out.put('-'); // and between terms (if needed);
else if (afterFirstTerm) // don't put '+' in front of
out.put('+'); // polynomial;
afterFirstTerm++;
if (abs(pol->coeff) != 1) // print a coefficient
out << ' ' << abs(pol->coeff);// if it is not 1 nor -1, or
else if (pol->vars.size() == 0) // the term has only a coefficient
out << " 1";
else out.put(' ');
for (i = 1; i <= pol->vars.size(); i++) {
out << pol->vars[i-1].id; // print a variable name
if (pol->vars[i-1].exp != 1) // and an exponent, only
out << pol->vars[i-1].exp; // if it is not 1;
}
}
out << endl;
return out;
}
};
// two terms are equal if all varibles are the same and
// corresponding variables are raised to the same powers;
// the first cell of the node containing a term is excluded
// from comparison, since it stores coefficient of the term;
bool Term::operator== (const Term& term) const {
int i;
for (i = 0; i < min(vars.size(),term.vars.size()) &&
vars[i] == term.vars[i]; i++);
return i == vars.size() && vars.size() == term.vars.size();
}
bool Term::operator< (const Term& term2) const { // used by sort();
if (vars.size() == 0)
return false; // *this is just a coefficient;
else if (term2.vars.size() == 0)
return true; // term2 is just a coefficient;
for (int i = 0; i < min(vars.size(),term2.vars.size()); i++)
if (vars[i].id < term2.vars[i].id)
return true; // *this precedes term2;
else if (term2.vars[i].id < vars[i].id)
return false; // term2 precedes *this;
else if (vars[i].exp < term2.vars[i].exp)
return true; // *this precedes term2;
else if (term2.vars[i].exp < vars[i].exp)
return false; // term2 precedes *this;
return ((int)vars.size() - (int)term2.vars.size() < 0) ? true : false;
}
Polynomial Polynomial::operator+ (Polynomial& polyn2) {
Polynomial result;
list<Term>::iterator p1, p2;
bool erased;
for (p1 = terms.begin(); p1 != terms.end(); p1++) // create a new polyn
result.terms.push_back(*p1); // from copies of *this
for (p1 = polyn2.terms.begin(); p1 != polyn2.terms.end(); p1++) // and
result.terms.push_back(*p1); // polyn2;
for (p1 = result.terms.begin(); p1 != result.terms.end(); ) {
for (p2 = p1, p2++, erased = false; p2 != result.terms.end(); p2++)
if (*p1 == *p2) { // if two terms are equal (except
p1->coeff += p2->coeff; // for the coefficient), add the
result.terms.erase(p2); // two coefficients and erase
if (p1->coeff == 0) // a redundant term; if the
result.terms.erase(p1);// coefficient in retained term
erased = true; // is zero, erase the term as well;
break;
}
if (erased) // restart processing from the beginning
p1 = result.terms.begin(); // if any node was erased;
else p1++;
}
result.terms.sort();
return result;
}
int main() {
Polynomial polyn1, polyn2;
cout << "Enter two polynomials, each ended with a semicolon:\n";
cin >> polyn1 >> polyn2;
cout << "The result is:\n" << polyn1 + polyn2;
return 0;
}
On line 52, the error function should take a const char*, rather than a char*:
void error(char* s) { // WRONG
void error(const char *s) { // RIGHT
cerr << s << endl; exit(1);
}
This is because strings like "Hello" are arrays of const char, because you can't modify literals. If you make this change, the code should work. The compiler won't convert pointers to const types to regular pointers, because that would break the constness.
Also, on line 82 ad 83, the textbook writes:
int i; // Error: i never initialized
for (int i = 0; isalnum(ch); i++) { // process this term:
It looks like it was trying to use i both inside and outside the for loop, but the author accidentally declared i a second time at the start of the loop. We can fix it by doing this:
int i = 0; // This is probably what was intended
for(; isalnum(ch); i++) { // process this term:
Why can't I modify string literals?
Imagine if you could do
5 = 10; // This is complete and utter nonsense.
This doesn't make any sense! You can't assign 5 to 10. In the same way, this is also nonsense:
"hello" = "blarg"; // This is also nonsense
"hello" is always "hello", and never anything else. If the compiler allowed you to write
"hello"[0] = 'H'; // This is also nonsense
This would be modifying "hello", which could just... break your program. It's wrong; it's evil. In fact, the string literal "hello" might even be placed in a section of memory that's flagged as const by the Operating System itself.
Why does the compiler give you the error (or warning)
If you have char*, that is a pointer to a char. If you have const char*, that is a pointer to a const char. If you could go from const char* to char*, this would allow you to modify const memory, which could break the program:
// If you could do this, you could modify "hello"
// Modifying "hello" is nonsense, so this should be nonsense too:
char* s = "hello";
s[0] = 'H'; // How you'd modify "hello"
As a result, string literals can only be assigned to const char*:
// Because s contains const chars, elements of s can't be modified so this is fine
const char* s = "hello"; // This is OK
Why did the textbook contain the error?
The language used to let people do really unsafe stuff, like modifying string literals. This is extremely bad practice and it breaks optimizations the compiler uses to make programs smaller and faster.
The textbook is probably written by someone who's used to writing old, unsafe code.
So I am working on some homework for my uni and need to convert a string to a float. For whatever reason g++ is complaining that the 'stof' function doesn't exist. Although I have included the required header. Here is my code, the error is on the line that says
holder = stof(x.substr(0, end_of_num));
#include <iostream>
#include <string>
#include <list>
using namespace std;
float process_func(string x);
bool isPartOfNum(char x);
int main() {
string x;
while (true) {
cout << "input a string" << endl;
getline(cin, x);
cout << process_func(x);
}
return 0;
}
float process_func(string x) {
int end_of_num =0;// used to find last index from num
int negMult = 1; //used to multiply value at end if there was a negative
bool onNum = false; //used to
list <float> numList;
list <char> operList;
if ((x.at(0) < 48 || x.at(0) > 57) && x.at(0) != '-') //check if start of string doesnt have a number or negative symbol
return -1;
if (x.at(0) != '-')
negMult = -1;
float holder;// temp holder for floats
int i = 0;
while (i<x.length()) {
if (isPartOfNum(x.at(i))) {
end_of_num++;
onNum = true;
}
else if (onNum) {
holder = stof(x.substr(0, end_of_num));
numList.push_back(holder); //adds num as float to list
x.erase(0, end_of_num + 1); //+1 removes the space after the number before the operator
end_of_num = 0;
onNum = false;
}
if (x.at(i) == '+' || x.at(i) == '-' || x.at(i) == '*' || x.at(i) == '/') {
operList.push_back(x.at(i));
}
} //at this point both lists should be full of all needed pieces of info
int answer = 0;
int temp;
bool firstOper=true; // used to hold first operation
while (numList.size() >=2) { //requires at least 2 entries for last operation
while (!operList.empty()) {
temp = numList.front();
numList.pop_front();
if (operList.front() == '+') {
if (firstOper) {
answer = temp + numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer += temp;
}
}
else if (operList.front() == '-') {
if (firstOper) {
answer = temp - numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer -= temp;
}
}
else if (operList.front() == '*') {
if (firstOper) {
answer = temp * numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer *= temp;
}
}
else if (operList.front() == '/') {
if (firstOper) {
answer = temp / numList.front();
numList.pop_front();
firstOper = false;
}
else {
answer /= temp;
}
}
operList.pop_front();
}
}
return answer;
}
bool isPartOfNum(char x) {
if ((x >= 48 && x <= 57) || (x == '-' || x == '.'))
return true;
return false;
}
Solved by compiling using c++ 11
The function dictionary_select returns a vector which contains words that are starting with W.
In this code dictionary_select gives an error message. But I can not find it. Is there anybody can help me?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct tree {
string data;
tree *left;
tree *right;
};
typedef tree* dictionary;
bool dictionary_ins_word(dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
tree* dic;
dic = new tree;
dic->data = W;
dic->left = NULL;
dic->right = NULL;
if(D == NULL) {
D = dic;
}
else {
if(W <= D->data)
dictionary_ins_word(D->left, W);
else
dictionary_ins_word(D->right, W);
}
return true;
}
bool dictionary_lookup(const dictionary & D, const string & W)
{
if(W == "" || W == " ")
return false;
if(D == NULL)
return false;
if(W == D->data)
return true;
else if (W < D->data)
return dictionary_lookup(D->left, W);
else
return dictionary_lookup(D->right, W);
}
bool dictionary_is_empty(const dictionary & D)
{
if(D == NULL)
return true;
else
return false;
}
bool dictionary_del_word(dictionary & D, const string & W)
{
if(!dictionary_lookup(D, W))
return false;
if(W < D->data)
dictionary_del_word(D->left, W);
else if(W > D->data)
dictionary_del_word(D->right, W);
else {
string item;
tree* temp;
temp = D;
if(D->left == NULL) {
D = D->right;
delete temp;
}
else if(D->right == NULL) {
D = D->left;
delete temp;
}
else {
while(D->left->right != NULL)
D->left = D->left->right;
item = D->left->data;
D->data = item;
dictionary_del_word(D->left, W);
}
}
return true;
}
bool dictionary_min(string & W, const dictionary & D)
{
dictionary min;
if(D == NULL)
return false;
min = D;
while(min->left != NULL)
min = min->left;
W = min->data;
return true;
}
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
return dictionary_select(D->left, W);
else
return dictionary_select(D->right, W);
}
int main()
{
bool b[5];
dictionary l;
string W, str;
vector <string> vec;
l = new tree;
l->data = "berdi";
l->left = NULL;
l->right = NULL;
b[0] = dictionary_ins_word(l, "atas");
b[1] = dictionary_ins_word(l, "cara");
b[2] = dictionary_ins_word(l, "ata");
b[3] = dictionary_ins_word(l, "atax");
vec = dictionary_select(l, "ata");
for(int i=0; i<vec.size(); i++) {
cout << vec[i] << " ";
}
getchar();
return 0;
}
The problem is your function dictionary_select declares the result vector and never returns it. Below is how you would change this:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVector; // add this to store the result from the recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(W <= D->data)
tempVector = dictionary_select(D->left, W); // get the recursion result
else
tempVector = dictionary_select(D->right, W); // get the recursion result
result.insert(result.end(), tempVector.begin(), tempVector.end()); // append all the results
return result; // return the result
}
UPDATE
In order for the function to return the correct data, you have to also ensure that you look at both left and right sides of the tree to get the appropriate results. The function below has the update:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > tempVectorLeft; // add this to store the result from the left recursion
vector < string > tempVectorRight; // add this to store the result from the right recursion
vector < string > zeroVec;
string temp;
zeroVec.push_back("");
if(D == NULL)
return zeroVec;
temp = D->data;
size_t found = temp.find(W);
if(found == 0)
result.push_back(D->data);
if(found == 0 || W <= D->data)
tempVectorLeft = dictionary_select(D->left, W); // store results
if(found == 0 || W > D->data)
tempVectorRight = dictionary_select(D->right, W); // store results
result.insert(result.end(), tempVectorLeft.begin(), tempVectorLeft.end()); // append all the left results
result.insert(result.end(), tempVectorRight.begin(), tempVectorRight.end()); // append all the right results
return result;
}
I propose you the following variant:
vector <string> dictionary_select(const dictionary & D, const string & W)
{
vector < string > result;
vector < string > zeroVec;
if (D == NULL)
return zeroVec;
string temp = D->data;
size_t found = temp.find(W);
if (found == 0)
result.push_back(D->data);
if (found || W <= D->data)
for(auto x: dictionary_select(D->left, W))
result.push_back(x);
if (found || W > D->data)
for (auto x : dictionary_select(D->right, W))
result.push_back(x);
return result;
}
The problem in the if / else approach used in you initial algortihm to choose between recureion on left or right node, is that you could have a note like this:
atar
/ \
ata atax
So if the data in the head of the node matches, you need to check both left and right to be sure that you're not missing something.
I'm trying to go through a vector of strings with an iterator, but it needs to check a few values in advance. I tried doing this with the following code:
typedef std::vector<std::string>::iterator Cursor;
std::string check(Cursor& at) {
int number;
std::string ans = *at;
if (ans.empty()) {
return "NOT OK";
} else {
std::stringstream ss(ans);
ss >> number >> ans;
if (ans == "NOT OK") {
return "NOT OK";
} else if (ans == "VALUE") {
int x;
ss >> x;
std::string result("OK");
for (Cursor c = at; x > 0; ++c, --x) {
result = check(c);
}
return result;
} else {
return "OK";
}
}
}
But this code crashes when it enters the for-loop and I have no idea why.
int x;
ss >> x; // Here you should check whether x has the expected value.
std::string result("OK");
for (Cursor c = at; x > 0; ++c, --x) { // here you do not check whether c is within boundaries.
result = check(c);
}
// c should start from at+1, otherwise it may result in infinite recursion.
// Also, termination condition should be added.
for (Cursor c = at+1; x > 0 && c != myVec.end(); ++c, --x) {