How does manipulation of a char array cause a stack overflow? - c++

If there is a blatantly obvious flaw, I'm sorry. I'm fairly new to memory, so I have some understanding on how stack overflows work and as far as I know, nothing I'm doing should cause a stack overflow. All I'm doing is changing the character in a string.
I know arrays are pointers, but would changing the value cause a stack overflow?
Here is the concerning function:
char base[] = "aaaaa";
void changeLetters(int position) { // Stack overflow happens around here
if (base[position] != 'z') {
base[position]++;
}
// When I include a cout here, I also get a stack overflow
if (position == 4 && base[position] != 'z') {
changeLetters(position);
}
else if (base[position] == 'z' && position != 0) {
base[position] = 'a';
changeLetters(position - 1);
}
else if (position < 4) {
changeLetters(position + 1);
}
}
When not having std::cout, I get the
Unhandled exception at 0x767C3210 (KernelBase.dll) in passwordCracker.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x01002FFC).
Otherwise
Unhandled exception at 0x009C38B9 in passwordCracker.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x006D2F8C).
Edit:
The function is called in the main loop. The value passed is the length of the string (4), and it works its way through. One odd thing I didn't mention is that it works perfectly if I cycle through a smaller amount of letters (a, b, c, d) but I only recieve a stack overflow if I have it cycle through the alphabet.

Your code is iterating over all strings of length 5 made up of the alphabet a-z. This is not a problem by itself, however you have to make sure that the maximal call depth is not too large.
In each iteration of changeLetters you are increasing at most one letter once and then call again to changeLetters and you make at most one such call.
Therefore your call graph is completely linear, for each of the 26^5 strings you are making another recursive call in depth and so the call stack at the end will be about that large. The problem is, that this is a very large number 26^5 = 11881376 and may easily be larger than the stack space you may use.
You need to make the linear call graph into one with branches, by e.g. using a loop over the current character's position instead of calling changeLetters each time.

The recursion isn't infinite, but it's deep. Deep enough to blow up the stack.
The function uses recursion each time it increments a letter. And because there are 5 characters holding 26 possible values each, the recursion is 265 = 11881376 levels deep. I'm not sure how big your stack is, but it's not big enough to handle that many levels. So you get a stack overflow.
Switch to an iterative solution using nested loops.

Related

unhandled exception, invalid parameter passed to a function that considers invalid paramaters fatal [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm using visual studio 2017, and coding under unreal engine coding standards, and its throwing an unhandled exception with invalid parameters passed to a function that considers them fatal. I can't figure it out, the VS2017 debugger is completely useless, and I'm pretty new to coding, can anyone throw me some suggestions? EDIT: The only thing that i can come close to finding is that it appears to be being cause by a string being out of range cause by an infinite loop somewhere in the function below.
FBullCowCount FBullCowGame::SubmitGuess(FText Guess)
{
// increment the turn number
MyCurrentTry++;
// setup a return variable
FBullCowCount BullCowCount;
// loop through all letters in the guess
int32 HiddenWordLength = MyHiddenWord.length();
for (int32 MHWChar = 0; MHWChar < HiddenWordLength; MHWChar++) {
// compare letters against the hidden word
for (int32 GChar = 0; GChar < HiddenWordLength; GChar++) {
//if they match then
if (Guess[MHWChar] == MyHiddenWord[MHWChar])
{
//increment bulls if they're in the same place
if (MHWChar == GChar) {
BullCowCount.Bulls++;
}
else {
BullCowCount.Cows++;
}
}
} //increment cows if not
}
return BullCowCount;
}
Your code comment says "loop through all letters in the guess", but your code loops through all letters of MyHiddenWord instead. That means that unless both Guess and MyHiddenWord have the exact same length, this:
if (Guess[MHWChar] == MyHiddenWord[MHWChar])
will at some point access an element of Guess that's out of range, and this is the likely cause of the exception, if FText happens to use a range-checked operator[].
What you probably want here is:
#include <algorithm>
// ...
auto HiddenWordLength = std::min(MyHiddenWord.length(), Guess.length());
It will limit the amount of letters to loop through to the shorter of the two strings.

Stack Overflow error with Vectors

I have the following code which causes stack overflow. I don't know why. None of the values I used is out of boundaries when exception occurs. It is called as this Contour_Depth_Search(0, tmp, 0); where tmp=0;
// Global Variables
vector<Vec4i> hierarchy;
vector<vector<Point>> approx_corners, contours;
vector<Point> temp_corner, fiducial_centers;`enter code here`
vector<vector<int>> index_value;
vector<vector<int>> index_depth;
void Contour_Depth_Search(int Indice, int &Nb_Solutions, int depth_level) {
// Check if current contour is part of a solution
if (approx_corners[Indice].size() == 4) {
if (!index_depth[Nb_Solutions].empty() && index_depth[Nb_Solutions].back() == depth_level) {
index_value[Nb_Solutions][index_value[Nb_Solutions].size() - 1] = Indice;
//index_depth[Nb_Solutions][index_depth[Nb_Solutions].size() - 1] = depth_level;
}
else {
index_value[Nb_Solutions].push_back(Indice);
index_depth[Nb_Solutions].push_back(depth_level);
}
}
// I can only search for deeper tree if I found a square in current level or no solutions is started yet (deeper_allowed)
if (hierarchy[Indice][2] != -1) {
Contour_Depth_Search(hierarchy[Indice][2], Nb_Solutions, depth_level+1);}
// I only go to next node if I cannot find a square in current contour
if (hierarchy[Indice][0] != -1) {
Contour_Depth_Search(hierarchy[Indice][0], Nb_Solutions, depth_level);}
if (index_value[Nb_Solutions].size() >= 8) {
Nb_Solutions++;
index_value.push_back(vector<int>());
index_depth.push_back(vector<int>());
}
else if (!index_value[Nb_Solutions].empty() && index_depth[Nb_Solutions].back() == depth_level) {
index_value[Nb_Solutions].pop_back();
index_depth[Nb_Solutions].pop_back();
}
return;
}
I found my solution via assigning my Stack:reserve as 2000000. I don't know why with 3000 elements I hit stack overflow, but w/o changing my code, there is no quick solution.
Since the stack grows downward in-memory, the size of the stack must be pre-defined. Stack overflow exceptions occur when stackPointer < topOfStack, meaning too much data was put on the stack.
In the case of your code, you seem to be using recursion (Contour_Depth_Search calls itself). When a function is called, information is passed around on the stack. As a result, stack overflows are a typical symptoms of unbound recursion. I suspect that is your issue. Without any of the input data it's not really possible for me to help you further, but you can debug it yourself to determine why it is recursing so deeply.

Recursive String Transformations

EDIT: I've made the main change of using iterators to keep track of successive positions in the bit and character strings and pass the latter by const ref. Now, when I copy the sample inputs onto themselves multiple times to test the clock, everything finishes within 10 seconds for really long bit and character strings and even up to 50 lines of sample input. But, still when I submit, CodeEval says the process was aborted after 10 seconds. As I mention, they don't share their input so now that "extensions" of the sample input work, I'm not sure how to proceed. Any thoughts on an additional improvement to increase my recursive performance would be greatly appreciated.
NOTE: Memoization was a good suggestion but I could not figure out how to implement it in this case since I'm not sure how to store the bit-to-char correlation in a static look-up table. The only thing I thought of was to convert the bit values to their corresponding integer but that risks integer overflow for long bit strings and seems like it would take too long to compute. Further suggestions for memoization here would be greatly appreciated as well.
This is actually one of the moderate CodeEval challenges. They don't share the sample input or output for moderate challenges but the output "fail error" simply says "aborted after 10 seconds," so my code is getting hung up somewhere.
The assignment is simple enough. You take a filepath as the single command-line argument. Each line of the file will contain a sequence of 0s and 1s and a sequence of As and Bs, separated by a white space. You are to determine whether the binary sequence can be transformed into the letter sequence according to the following two rules:
1) Each 0 can be converted to any non-empty sequence of As (e.g, 'A', 'AA', 'AAA', etc.)
2) Each 1 can be converted to any non-empty sequences of As OR Bs (e.g., 'A', 'AA', etc., or 'B', 'BB', etc) (but not a mixture of the letters)
The constraints are to process up to 50 lines from the file and that the length of the binary sequence is in [1,150] and that of the letter sequence is in [1,1000].
The most obvious starting algorithm is to do this recursively. What I came up with was for each bit, collapse the entire next allowed group of characters first, test the shortened bit and character strings. If it fails, add back one character from the killed character group at a time and call again.
Here is my complete code. I removed cmd-line argument error checking for brevity.
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>
using namespace std;
//typedefs
typedef string::const_iterator str_it;
//declarations
//use const ref and iterators to save time on copying and erasing
bool TransformLine(const string & bits, str_it bits_front, const string & chars, str_it chars_front);
int main(int argc, char* argv[])
{
//check there are at least two command line arguments: binary executable and file name
//ignore additional arguments
if(argc < 2)
{
cout << "Invalid command line argument. No input file name provided." << "\n"
<< "Goodybe...";
return -1;
}
//create input stream and open file
ifstream in;
in.open(argv[1], ios::in);
while(!in.is_open())
{
char* name;
cout << "Invalid file name. Please enter file name: ";
cin >> name;
in.open(name, ios::in);
}
//variables
string line_bits, line_chars;
//reserve space up to constraints to reduce resizing time later
line_bits.reserve(150);
line_chars.reserve(1000);
int line = 0;
//loop over lines (<=50 by constraint, ignore the rest)
while((in >> line_bits >> line_chars) && (line < 50))
{
line++;
//impose bit and char constraints
if(line_bits.length() > 150 ||
line_chars.length() > 1000)
continue; //skip this line
(TransformLine(line_bits, line_bits.begin(), line_chars, line_chars.begin()) == true) ? (cout << "Yes\n") : (cout << "No\n");
}
//close file
in.close();
return 0;
}
bool TransformLine(const string & bits, str_it bits_front, const string & chars, str_it chars_front)
{
//using iterators so store current length as local const
//can make these const because they're not altered here
int bits_length = distance(bits_front, bits.end());
int chars_length = distance(chars_front, chars.end());
//check success rule
if(bits_length == 0 && chars_length == 0)
return true;
//Check fail rules:
//1. next bit is 0 but next char is B
//2. bits length is zero (but char is not, by previous if)
//3. char length is zero (but bits length is not, by previous if)
if((*bits_front == '0' && *chars_front == 'B') ||
bits_length == 0 ||
chars_length == 0)
return false;
//we now know that chars_length != 0 => chars_front != chars.end()
//kill a bit and then call recursively with each possible reduction of front char group
bits_length = distance(++bits_front, bits.end());
//current char group tracker
const char curr_char_type = *chars_front; //use const so compiler can optimize
int curr_pos = distance(chars.begin(), chars_front); //position of current front in char string
//since chars are 0-indexed, the following is also length of current char group
//start searching from curr_pos and length is relative to curr_pos so subtract it!!!
int curr_group_length = chars.find_first_not_of(curr_char_type, curr_pos)-curr_pos;
//make sure this isn't the last group!
if(curr_group_length < 0 || curr_group_length > chars_length)
curr_group_length = chars_length; //distance to end is precisely distance(chars_front, chars.end()) = chars_length
//kill the curr_char_group
//if curr_group_length = char_length then this will make chars_front = chars.end()
//and this will mean that chars_length will be 0 on next recurssive call.
chars_front += curr_group_length;
curr_pos = distance(chars.begin(), chars_front);
//call recursively, adding back a char from the current group until 1 less than starting point
int added_back = 0;
while(added_back < curr_group_length)
{
if(TransformLine(bits, bits_front, chars, chars_front))
return true;
//insert back one char from the current group
else
{
added_back++;
chars_front--; //represents adding back one character from the group
}
}
//if here then all recursive checks failed so initial must fail
return false;
}
They give the following test cases, which my code solves correctly:
Sample input:
1| 1010 AAAAABBBBAAAA
2| 00 AAAAAA
3| 01001110 AAAABAAABBBBBBAAAAAAA
4| 1100110 BBAABABBA
Correct output:
1| Yes
2| Yes
3| Yes
4| No
Since a transformation is possible if and only if copies of it are, I tried just copying each binary and letter sequences onto itself various times and seeing how the clock goes. Even for very long bit and character strings and many lines it has finished in under 10 seconds.
My question is: since CodeEval is still saying it is running longer than 10 seconds but they don't share their input, does anyone have any further suggestions to improve the performance of this recursion? Or maybe a totally different approach?
Thank you in advance for your help!
Here's what I found:
Pass by constant reference
Strings and other large data structures should be passed by constant reference.
This allows the compiler to pass a pointer to the original object, rather than making a copy of the data structure.
Call functions once, save result
You are calling bits.length() twice. You should call it once and save the result in a constant variable. This allows you to check the status again without calling the function.
Function calls are expensive for time critical programs.
Use constant variables
If you are not going to modify a variable after assignment, use the const in the declaration:
const char curr_char_type = chars[0];
The const allows compilers to perform higher order optimization and provides safety checks.
Change data structures
Since you are perform inserts maybe in the middle of a string, you should use a different data structure for the characters. The std::string data type may need to reallocate after an insertion AND move the letters further down. Insertion is faster with a std::list<char> because a linked list only swaps pointers. There may be a trade off because a linked list needs to dynamically allocate memory for each character.
Reserve space in your strings
When you create the destination strings, you should use a constructor that preallocates or reserves room for the largest size string. This will prevent the std::string from reallocating. Reallocations are expensive.
Don't erase
Do you really need to erase characters in the string?
By using starting and ending indices, you overwrite existing letters without have to erase the entire string.
Partial erasures are expensive. Complete erasures are not.
For more assistance, post to Code Review at StackExchange.
This is a classic recursion problem. However, a naive implementation of the recursion would lead to an exponential number of re-evaluations of a previously computed function value. Using a simpler example for illustration, compare the runtime of the following two functions for a reasonably large N. Lets not worry about the int overflowing.
int RecursiveFib(int N)
{
if(N<=1)
return 1;
return RecursiveFib(N-1) + RecursiveFib(N-2);
}
int IterativeFib(int N)
{
if(N<=1)
return 1;
int a_0 = 1, a_1 = 1;
for(int i=2;i<=N;i++)
{
int temp = a_1;
a_1 += a_0;
a_0 = temp;
}
return a_1;
}
You would need to follow a similar approach here. There are two common ways of approaching the problem - dynamic programming and memoization. Memoization is the easiest way of modifying your approach. Below is a memoized fibonacci implementation to illustrate how your implementation can be speeded up.
int MemoFib(int N)
{
static vector<int> memo(N, -1);
if(N<=1)
return 1;
int& res = memo[N];
if(res!=-1)
return res;
return res = MemoFib(N-1) + MemoFib(N-2);
}
Your failure message is "Aborted after 10 seconds" -- implying that the program was working fine as far as it went, but it took too long. This is understandable, given that your recursive program takes exponentially more time for longer input strings -- it works fine for the short (2-8 digit) strings, but will take a huge amount of time for 100+ digit strings (which the test allows for). To see how your running time goes up, you should construct yourself some longer test inputs and see how long they take to run. Try things like
0000000011111111 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBAAAAAAAA
00000000111111110000000011111111 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBAAAAAAAA
and longer. You need to be able to handle up to 150 digits and 1000 letters.
At CodeEval, you can submit a "solution" that just outputs what the input is, and do that to gather their test set. They may have variations so you may wish to submit it a few times to gather more samples. Some of them are too difficult to solve manually though... the ones you can solve manually will also run very quickly at CodeEval too, even with inefficient solutions, so there's that to consider.
Anyway, I did this same problem at CodeEval (using VB of all things), and my solution recursively looked for the "next index" of both A and B depending on what the "current" index is for where I was in a translation (after checking stoppage conditions first thing in the recursive method). I did not use memoization but that might've helped speed it up even more.
PS, I have not run your code, but it does seem curious that the recursive method contains a while loop within which the recursive method is called... since it's already recursive and should therefore encompass every scenario, is that while() loop necessary?

Encountering stack overflow while implementing recursive Bubble sort

Hey I converted this C# code to c++ as
void bubbleSort(int *inputArray, int passStartIndex, int currentIndex,int length)
{
if(passStartIndex == length - 1) return;
if(currentIndex == length - 1) return bubbleSort(inputArray, passStartIndex+1, passStartIndex+1,length);
//compare items at current index and current index + 1 and swap if required
int nextIndex = currentIndex + 1;
if(inputArray[currentIndex]>inputArray[nextIndex])
{
int temp = inputArray[nextIndex];
inputArray[nextIndex] = inputArray[currentIndex];
inputArray[currentIndex] = temp;
}
return bubbleSort(inputArray, passStartIndex, currentIndex + 1,length);
}
but when I execute it on input array of having length 50100, it shows me expcetion
System.StackOverflowException was unhandled Message: An unhandled
exception of type 'System.StackOverflowException' occurred in example.exe
What am I doing wrong? How to fix it?
"What am I doing wrong?"
Each time recursive function calls itself, the call frame (activation record) is stored into the stack memory. So when the recursion gets too deep, which is the moment when you reach the maximum size of stack, the execution is terminated.
Also have a look at: Does C++ limit recursion depth?
"How to fix it?"
The easiest way how to avoid this problem is to never design your algorithm as a recursion at first place. But once you already have a recursive solution like this, in most cases it's possible to rewrite it into the loop form or (which is usually much easier): a tail recursion.
Basically if you can rewrite your function in a way that it never directly passes any arguments to the next call, you won. If you look at your recursion, there are 2 spots, where it calls itself and before the call is made, only currentIndex and passStartIndex are being changed. Imagine that you would store these indexes somewhere aside and the current function call would just signal "I'm done, these are values that someone should continue with: ... Now you may continue!", which means that state, the function is at, is not needed to be stored. By doing so you'll end up with a Tail call (see especially first example program).
Here's the full example of how it could be done with your code: Step 1, Step 2
It will not solve your problem (see recursion limit), but there is a mistake in the algorithm that you used. You should replace
if (currentIndex == length - 1)
return bubbleSort(inputArray, passStartIndex+1, passStartIndex+1, length);
by
if (currentIndex == length - 1)
return bubbleSort(inputArray, passStartIndex+1, 0,length - 1);
The bubble sort should restart to 0, because the first item is not at the right place, but the last one is.

Using Stacks in C++ to Evaluate the Postfix Expression

Ok, I already have it in postfix notation and I am sending over a string variable that will have the postfix notation as something such as: 5 15 2 *+
Here is my code:
int evaluatePostFix(string postfix_expression){
//Create a new stack
stack<int> theStack;
//Loops while the postfix expression string still contains values
while(postfix_expression.length()>=1){
//Loops on a number an whitespace
while(isdigit(postfix_expression.at(0)) || isspace(postfix_expression.at(0))){
//Holds a number that is above two digits to be added to the stack
string completeNum;
if(isdigit(postfix_expression.at(0))){
//Add the digit so it can become a full number if needed
completeNum+=postfix_expression.at(1);
}
else {
//Holds the integer version of completeNum
int intNum;
//Make completeNum an int
intNum=atoi(completeNum.c_str());
//push the number onto the stack
theStack.push(intNum);
}
//Check to see if it can be shortened
if(postfix_expression.length()>=1){
//Shorten the postfix expression
postfix_expression=postfix_expression.substr(1);
}
}
//An Operator has been found
while(isOperator(postfix_expression.at(0))){
int num1, num2;
char op;
//Grabs from the top of the stack
num1=theStack.top();
//Pops the value from the top of the stack - kinda stupid how it can return the value too
theStack.pop();
//Grabs the value from the top of the stack
num2=theStack.top();
//Pops the value from the top of the stack
theStack.pop();
//Grab the operation
op=postfix_expression.at(0);
//Shorten the postfix_expression
postfix_expression=postfix_expression.substr(1);
//Push result onto the stack
theStack.push(Calculate(num1,num2, op));
}
}
return theStack.top();
}
The error I get is "Deque iterator not deferencable"
Any help that I can get on this error would be much appreciated.
btw I haven't used C++ in a couple of years so I'm a bit rusty.
It would be easier if you told us which line was causing the error by stepping through with a debugger. However, I think I may have spotted the error.
In this block of code
if(isdigit(postfix_expression.at(0))){
//Add the digit so it can become a full number if needed
completeNum+=postfix_expression.at(1);
}
You ask for the postfix_expression.at(1) without ever checking if that element exists. Since there is no check, you might be accessing bad memory locations.