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.
Related
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.
I am having two main issues implementing the algorithm described in this article in C++: properly terminating the algorithm and freeing up dynamically allocated memory without running into a seg fault.
Here is the pseudocode provided in the article:
RBFS (node: N, value: V, bound: B)
IF f(N)>B, return f(N)
IF N is a goal, EXIT algorithm
IF N has no children, RETURN infinity
FOR each child Ni of N,
IF f(N) < V AND f(Ni) < V THEN F[i] := V
ELSE F[i] := f(Ni)
sort Ni and F[i] in increasing order of F[i]
IF only one child, F[2] := infinity
WHILE (F[1] <= B)
F[1] := RBFS(N1, F[1], MIN(B, F[2]))
insert N1 and F[1] in sorted order
return F[1]
Here, f(Ni) refers to the "computed" function value, whereas F[i] refers to the currently stored value of f(Ni).
Here is my C++ implementation, in which I had to use a global variable to keep track of whether the goal had been reached or not (note, I am trying to maximize my f(n) value as opposed to minimizing, so I reversed inequalities, orders, min/max values, etc.):
bool goal_found = false;
bool state_cmp(FlowState *lhs, FlowState *rhs)
{
return (lhs->value > rhs->value);
}
int _rbfs(FlowState *state, int value, int bound)
{
if (state->value < bound) // Returning if the state value is less than bound
{
int value = state->value;
delete state;
return value;
}
if (state->is_goal()) // Check if the goal has been reached
{
cout << "Solved the puzzle!" << endl;
goal_found = true; // Modify the global variable to exit the recursion
return state->value;
}
vector<FlowState*> children = state->children();
if (children.empty())
{
//delete state; // Deleting this state seems to result in a corrupted state elsewhere
return INT_MIN;
}
int n = 0; // Count the number of children
for (const auto& child: children)
{
if (state->value < value && child->value < value)
child->value = value;
else
child->update_value(); // Equivalent of setting stored value to static value (F[i] := f(Ni))
++n;
}
sort(children.begin(), children.end(), state_cmp);
while (children.front()->value >= bound && !goal_found)
{// Loop depends on the global goal_found variable since this is where the recursive calls happen
if (children.size() < 2)
children.front()->set_value(_rbfs(children.front(), children.front()->value, bound));
else
children.front()->set_value(_rbfs(children.front(), children.front()->value, max(children[1]->value, bound)));
}
// Free children except the front
int i;
for (i = 1; i < n; ++i)
delete children[i];
state->child = children.front(); // Records the path
return state->child->value;
}
void rbfs(FlowState* initial_state)
{
// This is the actual function I invoke to call the algorithm
_rbfs(initial_state, initial_state->get_value(), INT_MIN);
print_path(initial_state);
}
My main questions are:
Is there a way to terminate this function than having to use a global variable (bool goal_reached) without a complete re-implementation? Recursive algorithms usually have some kind of base-case to terminate the function, but I am not seeing an obvious way of doing that.
I can't seem to delete the dead-end state (when the state has no children) without running into a segmentation fault, but not deleting it results in unfreed memory (each state object was dynamically allocated). How can I modify this code to ensure that I've freed all of the states that pass through it?
I ran the program with gdb to see what was going on, and it appears that after deleting the dead-end state, the next state that is recursively called is not actually NULL, but appears to be corrupted. It has an address, but the data it contains is all junk. Not deleting that node lets the program terminate just fine, but then many states aren't getting freed. In addition, I had originally used the classical, iterative best-first search (but it takes up far too much memory for my case, and is much slower), and in that case, all dynamically allocated states were properly freed so the issue is in this code somewhere (and yes, I am freeing each of the states on the path in main() after calling rbfs).
In your code, you have
children.front()->set_value(_rbfs(children.front(), ...
where state inside of _rbfs is thus children.front().
And in _rbfs, you sometimes delete state. So children.front() can be deleted and then called with ->set_value. There's your problem.
Is there any reason why you calling delete at all?
I've run into this error before, but the circumstances baffle me as I have run nearly this exact set of functions without having this issue.
Let me break it down:
The error is being caused by the resize() private member function of a custom priority queue I am working on. It is all centered around de-allocating the pointer to the old queue array. Before I explain any further, let me list the handful of relatively small functions I've isolated the problem to.
void unfairQ::enqueue(int val)
{
if (isFull())
resize();
numElements++;
ageCount++;
heapArr[numElements].data = val;
heapArr[numElements].age = 1;
heapArr[numElements].priority = heapArr[numElements].data;
heapifyUp(numElements);
if (ageCount == 100) {
heapSort();
ageCount = 0;
}
return;
}
bool unfairQ::isFull()
{
return (numElements == capacity);
}
void unfairQ::resize()
{
int newCap = (capacity * 1.5);
queueNode *tempHeap = new queueNode[newCap];
for (int i = 1; i <= numElements; i++) {
tempHeap[i].data = heapArr[i].data;
tempHeap[i].age = heapArr[i].age;
tempHeap[i].priority = heapArr[i].priority;
}
// delete [] heapArr;
capacity = newCap;
heapArr = tempHeap;
return;
}
The commented out line in the resize function is the one causing problems. If I do delete the pointer to the array I get the "double free" error, however if I remove that line I get a "free(): invalid next size (normal):" if I enqueue enough values to require a second resize().
Please let me know if you need any more information or if I need to clarify anything.
You seem to be using your array with indexes starting from 1, c++ uses indexes starting from 0. This can cause a buffer overflow.
For example:
If capacity is currently 5 (so heapArray can have 5 entries) andnumElementsis currently 4, yourisFullwill returnfalse(correctly), however yourenqueuecode then incrementsnumElements(from 4 to 5) and attempts to write toheapArray[5]` which is out of bounds and may overwrite some other memory.
Solution: start your indexes from 0, e.g. in the enqueue function, increment numElements after you write the data heapArray[numElements]
I found the problem, while I was referencing/incrementing/decrementing all the indices correctly and calling the appropriate functions at the appropriate times, I was operating under the notion that I was working with indices 1-size, but in the constructor (something I hadn't glanced at for a while) I'd initialized numElements as 0 which broke the whole gosh darned thing.
Fixed that and now everything is hunky dory!
Thanks for the help guys.
I am writing a quicksort program. For that I need to partition the array. The partitioning is done by a function paritionIt(). I wrote a code of partitioning the array which is as follows:
int partition(int beg,int end,double key)
{
int pLeft = beg;
int pRight = end-1;
while(pLeft<pRight)
{
while(array[++pLeft]<key);
while(array[--pRight]>key);
if(pLeft<pRight)
swap(pLeft,pRight);
}
swap(pLeft,end-1);
return pLeft;
}
This block seems to work to work fine when executed in isolation. However, when ran along with the other functions, it seems to generate wrong answer. The following code given to me makes all the problems vanish but it doesn't seem much different from my code.
int partitionIt(int left, int right, double pivot)
{
int leftMark = left; //right of first elem
int rightMark = right - 1; //left of pivot
while(true)
{
while( theVect[++leftMark] < pivot ) //find bigger
; // (nop)
while( theVect[--rightMark] > pivot ) //find smaller
; // (nop)
if(leftMark >= rightMark) //if pointers cross,
break; // partition done
else //not crossed, so
swap(leftMark, rightMark); //swap elements
} //end while(true)
swap(leftMark, right-1); //restore pivot
return leftMark; //return pivot location
} //end partitionIt()
The block seems to be similar to mine but is giving the right answer whereas mine is not. Can you please me by telling what's the difference between partition() and partitionIt().
The difference is where you're breaking out of your looping structure.
In your code, you're making two conditional checks, whereas in the given code, you're only making one.
Assume you've been iterating through the loop for a while. (No pun intended).
You'll hit this code:
if(pLeft<pRight)
swap(pLeft,pRight);
Then you'll hit the bottom of the while loop, come back to the top, and then check again if pLeft<pRight. If this isn't true, we exit the loop.
In the given code, you perform the swap, but then you do the following:
while( theVect[++leftMark] < pivot ) //find bigger
; // (nop)
while( theVect[--rightMark] > pivot ) //find smaller
; // (nop)
You then check to see if you break out of the loop.
This seems to be where the difference lies.
Edit: To clarify - what happens if while(pLeft>=pRight) when you first enter the loop?
In the given code, you continue through the while loop until it breaks, but in your code, you never enter the body of the loop.
The only thing I see immediately is that the functions will
behave differently if called with left + 1 == right: your
function will not enter the loop, but will return beg; the
function from the book will enter the loop, thus incrementing
leftMark and decrementing rightMark before doing the final
swap and returning leftMark.
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.