Stack OverFlow with Recursion - c++

There is a stack overflow from my code I do not really know what is causing it. Parent is a fixed array like 14.
protected:
int* parent = new int[14];
int size = 14;
int Tree::level(int i) {
int count = 0;
for (int j = 0; j < size; j++) {
if (parent[i] == -1) {
count = 1;
} else {
count = level(i) + 1; //this is causing the stack Overlow
}
}
return count;
}

The recursive call in the following call is bound to cause an infinite recursion since i is not changed in the function.
count = level(i) + 1;
I am guessing that you meant to use j or parent[i] instead of i in that call. It's hard to tell what is the right value to use in the recursive call without more context.

In case of condition parent[i] == -1 false, function "level" becomes infinite recursive and hence stack overflow.

Related

How to fix "runtime error: reference binding to null pointer of type 'value_type' (stl_vector.h)" in leetcode?

I am doing leetcode 376. Wiggle Subsequence.
It went wrong when testing the first instance of input [1,7,4,9,2,5]. It showed that "Line 922: Char 34: runtime error: reference binding to null pointer of type 'value_type' (stl_vector.h)". Could anyone tell me what is going wrong? Thanks a lot!
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if(nums.size() < 2){
return nums.size();
}
std::priority_queue<int> big_heap;
vector<int> flag;
int result;
int length = nums.size();
for(int i = 0; i + 1 < length; i++){
if(nums[i+1] > nums[i]){
flag[i] = 1;
}
else if(nums[i+1] < nums[i]){
flag[i] = -1;
}
else{
flag[i] = 0;
}
}
int count = 1;
for(int i = 0; i + 2 < length;i++){
cout <<flag[i]<<endl;
if(flag[i] + flag[i+1] == 0){
count ++;
}
else{
big_heap.push(count);
count = 1;
}
}
big_heap.push(count);
result = big_heap.top() + 1;
return result;
}
};
You have undefined behavior, because you are accessing elements of flag while it has size 0.
If you want to write to flag[i] you first need to have an ith element in flag. You can achieve this by resizing flag to the length required, if you know it beforehand. In your case it seems like you will have exactly length-1 elements, so you can do
flag.resize(length-1);
or if you move the declaration after the the one of length, you can directly use std::vectors constructor to do this:
std::vector<int> flag(length-1);
Alternatively you can use push_back to insert elements at the end of the vector, if you are simply writing sequentially new elements, as you seem to be doing here, e.g. instead of flag[i] = 1;:
flag.push_back(1);

How can I avoid dividing by zero without too many conditionals?

I have an integer parameter which is supposed to control how many times in a particular run an event occurs.
For example, if the number of iterations for each run is 1000, then the parameter FREQ would be 5, if I wanted to have the event occur every 200 iterations. However, I want to be able to change the number of iterations, but keep the ratio the same, and also to be able to set the FREQ parameter to 0 if I don't want the event to occur at all.
Here is what I am currently using:
int N_ITER = 1000;
int FREQ = 5;
void doRun(){
int count = 0;
for (int i = 0; i < N_ITER; ++i){
if (FREQ > 0){
if (count < N_ITER/FREQ){
doSomething();
count++;
}
else{
doSomethingElse();
count = 0;
}
}
else{
doSomething();
}
}
}
This works fine, but it doesn't sit right with me having the nested conditionals, especially when I have two lots of doSomething(), I feel like it should be able to be accomplished more easily than that.
I tried making the one conditional if (FREQ > 0 && count < N_ITER/FREQ) but obviously that threw a Floating point exception because of the divide by zero.
I also tried using a try/catch block, but it really was no different, in terms of messiness, to using the nested conditionals. Is there a more elegant solution to this problem?
How about rearranging the condition? Instead of count < N_ITER/FREQ, use count*FREQ < N_ITER. If FREQ = 0, the expression will still be true.
int N_ITER = 1000;
int FREQ = 5;
void doRun() {
int count = 0;
for (int i = 0; i < N_ITER; ++i) {
if (count*FREQ < N_ITER) {
doSomething();
count++;
} else {
doSomethingElse();
count = 0;
}
}
}

Function returning the wrong value

This project is a homework assignment for school. The instructor has asked us to input 20 random integers then print the smallest in the list and then search the list for the first iteration of the number entered. My problem is returning the smallest number of the list. The function, shown below accepts an integer array and an integer with the size of the array. In Visual Studio, the tests for the smallest number work until the function returns the value. Instead of returning the smallest number, the function returns some kind of default value as opposed to the smallest integer. I have been staring at this code for the past two hours, any help would be appreciated.
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 0; i <= number_used; i++)
{
if (temp >= a[i])
{
temp = a[i];
}
}
return temp;
}
Your program has undefined behavior because you are accessing the array a using an invalid index.
When an array has 20 elements, the valid indices are 0-19, not 0-20.
You are using
for (int i = 0; i <= number_used; i++)
and then accessing a[i] in the loop. If number_used is equal to 20, you are accessing a using and index value of 20, which is not correct.
Change that to use i < number_used.
for (int i = 0; i < number_used; i++)
A minor issue is that you are using temp >= a[i], which can be changed to use temp > a[i]. Use of >= in this case will work but it will do more work than necessary.
Here's an updated version of the function:
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 1; i < number_used; i++)
{
if (temp > a[i])
{
temp = a[i];
}
}
return temp;
}
Assuming number_used is the size of array, code can be written as:
int theSmallest(const int a[], int number_used)
{
if( a == nullptr or number_used == 0 )
throw std::runtime_error( "invalid argument" );
return *std::min_element( a, a + number_used );
}
Note: you code has issue in case number_used is equal to 0 or a pointer is passed as nullptr, you may not expect that to happen but it is good idea to always validate your input (at least by assert())
Change to i < number_used and I think change to if(temp > a[i]).
You can also start i=1 since you made the assumption index 0 is the smallest.
Change
for (int i = 0; i <= number_used; i++)
to
for (int i = 1; i < number_used; i++)

Recursion call failure

I'm creating a suduko generator and I either get a stack overflow when calling a function using recursion or it doesn't call the function when it is being called with the class, I can't explain very well what is happening but this is the code:
sudoku::sudoku()
{
srand((unsigned int)time(NULL));
generate(); // call the generate function
display(1);
}
sudoku::~sudoku()
{}
bool sudoku::validate(){ //makes sure not more than one of the same number in row/column
for (int x = 0; x < size; x++){
for (int y = 0; y < size; y++){
if (number == Array[x][y])
return true;
}
}
return false;
}
void sudoku::generate(){ // generates sudoku numbers which is 9x9
for (int x = 0; x < size; x++){
for (int y = 0; y < size; y++){
number = 1;
if (validate() == true){
generate(); //get a stack overflow with this call
//if I change "generate" to "sudoku generate" the
//stack overflow doesn't happen but then the function
} //is not called, the if statement just skips to the else
else{
Array[x][y] = number;
}
}
}
}
is there a way to call "sudoku generate()" without the if statement skipping the condition even when it is true? Or is there another way of doing this?
First of all the if statement is redundant
if(validate()==true)
validate returns a boolean right? why equate this to another boolean you can write this as:
if(validate())
The stack overflow might be caused of too many calls of the generate() and validate() function, remember each call of the recursion pushes another instance of this functions to the stack. To solve this you might want to take a look at the principles of communicating vases : https://www.youtube.com/watch?v=q1G6S0DbnJY
or you can audit this course on edX which gives a quick look at invariant programming and principles of communicating vases : https://courses.edx.org/courses/LouvainX/Louv1.01x/1T2014/info

c++ BWAPI exception access violation

is there anybody using BWAPI who gets access violation error when accessing the Unit objects of the current game?
i am certain that the error is not in my code.. anyway.. is there anything i can do to avoid access violation?
i am getting this error sometimes at line with the comment bellow.. this code bellow execute many times and only sometimes i get the error..
int Squad::getSize() {
int no = 0;
for (int i = 0; i < (int) agents.size(); i++) {
BaseAgent* agent = agents.at(i);
if (agent != NULL && agent->isAlive() && agent->getUnit() != NULL && !agent->getUnit()->isBeingConstructed()) // this line
no++;
}
return no;
}
this is the code that I use to remove an BaseAgent from the vector.. analyze that and see if i can do it better:
void AgentManager::cleanup() {
//Step 2. Do the cleanup.
int cnt = 0;
int oldSize = (int)agents.size();
for (int i = 0; i < (int)agents.size(); i++) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.erase(agents.begin() + i);
cnt++;
i--;
}
}
int newSize = (int)agents.size();
}
the BaseAgent code is on this link
I would speculate that this line:
BaseAgent* agent = agents.at(i);
is returning some invalid pointer which is not set to 0.
Looking at your cleanup code, it looks a bit complicated. I would suggest
looping over the entire vector, deleting the dead elements and
setting the pointers to 0.
After the loop, use the erase-remove idiom to remove all NULL pointers from the vector.
step 1
for (unsigned int i = 0; i < agents.size(); ++i) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.at(i) = 0;
}
step 2
agents.erase(std::remove(agents.begin(), agents.end(), 0), agents.end());