Special Fibonacci and SIGSEGV - c++

#include<bits/stdc++.h>
#define big 1000000007
using namespace std;
long long n,k;
int fobo(int);
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
k=fobo(n)%big;
printf("%d",k);
printf("\n");
}
return 0;
}
int fobo(int m)
{
if(m==1)
return 0;
if(m==2)
return 1;
return 3*fobo(m-1)+2*fobo(m-2)+5;
}
The above code is for printing the sum of a special kind of Fibonnacci series following the relation given in the recurrence relation inside the function fobo . The code works fine on my machine but on testing in any online judge , the same code shows SIGSEGV error. There is no use of any arrays in the program , accessing unknown memory that i know of. I guess these are the some of the major requirements for having a SIGSEGV error. I cant find any in here . Please help me in resolving or finding the error.

If I had to guess, this looks like a stack overflow error. Try feeding 0 into fobo. When that happens, your base cases don't trigger because neither one checks for zero. You then call fobo(-1) and fobo(-2), which will start a chain of recursive calls of the form fobo(-2), fobo(-3), fobo(-4), etc. until you eventually overflow the stack.
To fix this, consider adding in a new base case for 0 in your code, or alternatively put in a general check to handle the case where the input is negative.
EDIT: Based on the comments, I think the main issue here is that if you call this function with a large input, you'll get a stack overflow before the recursion terminates. To address this, consider computing your values bottom-up using dynamic programming. I suspect that's what the question is ultimately trying to get at. Alternatively, use a different recursive formulation amenable to tail call elimination. If you're not familiar with these techniques, look online - you'll learn a lot in the process!

Related

swapping first and last element in stack c++ using stl

i created an account so i can get some help with stacks in STL , i need to write a function that takes stack as a parameter and swaps the first element with the last element , i searched the site for some help i found one :"https://stackoverflow.com/a/36188943/9990214" , i tried the same thing , but i keep getting this error : expression must have a constant value with red line under "int tmp[sz-1];".
it keeps giving me the error before reaching the main , any help would be appreciated , keep in mind am trying to write the function using STL.
ps : i tried replying with a comment to the person who answered the question but it's not allowing me to do that because i need 50 reputation.
using namespace std;
void rev(stack<int>&x){
int sz=x.size(),mytop,mybottom;
mytop=x.top();
x.pop();
int tmp[sz-1],i=0;
while(!x.empty()){
mybottom=x.top();
tmp[i++]=mybottom;
x.pop();
}
stack<int> returnIt;
returnIt.push(mybottom);
for(i=0;i<=sz-3;i++){
returnIt.push(tmp[i]);
}
returnIt.push(mytop);
while(!returnIt.empty()){
int tt=returnIt.top();
x.push(tt);
returnIt.pop();
}
}
The reason you're getting an error is that variable-length arrays are not a part of standard C++. This matters for your definition of tmp:
int tmp[sz-1], i=0; //sz is not known at compile-time, therefore, this is invalid code
Some compilers will allow code like this by allowing VLA's, but not being standard, you should use a different solution. Usually, for tasks like this, std::vector is ideal:
std::vector<int> tmp(sz - 1);
int i = 0;
This should compile (so long as you #include<vector> alongside your other includes), and should have the behavior you expect from your code.

3-way mergesort stackoverflow error in c++

hi guys can anyone tell me what's wrong with my 3-way mergesort code?the code I wrote can only sort 4 numbers if you give it more than 4 numbers(by changing size) it ends up with stack overflow error,here is the code:
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;
const int size=4;
vector <int> s(size);
void merge(int,int,int);
void mergesort(int,int);
int main(){
for(int i=0;i<size;i++){
cout<<"enter number "<<i+1<<":";
cin>>s.at(i);
}
system("CLS");
cout<<"here are the unsorted numbers:\n";//prints the input values so U can see'em
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
mergesort(0,size-1);//calls mergesort
cout<<"\nhere are the sorted numbers:\n";
for(int j=0;j<size;j++)
cout<<s.at(j)<<".";
cin.get();
cin.get();
return 0;
}
void merge(int low,int one_third,int high){
int i=low;
int j=one_third+1;
int k=0;
int length=(high-low)+1;
vector <int> u(length,0);
if(k<length){
while((i<=one_third)&&(j<=high)){
if(s.at(i)<=s.at(j)){
u.at(k)=s.at(i);
i++;
k++;
}//end for
else{
u.at(k)=s.at(j);
j++;
k++;
}//end elseif
}//end while
if(j>high)
while(i<=one_third)
{
u.at(k)=s.at(i);
i++;
k++;
}
if(i>one_third)
while(j<=high)
{
u.at(k)=s.at(j);
j++;
k++;
}
for(int n=low;n<k;n++)
s.at(n)=u.at(n);
}
}//end if
void mergesort(int low,int high){
if(low<high){
int one_third=(high-low)/3;//division,it's 3-way mergesort so obviously it's divided by 3
int two_third=2*one_third;
mergesort(low,one_third);
mergesort(one_third+1,two_third);
mergesort(two_third+1,high);
merge(low,one_third,two_third);
merge(low,two_third,high);
}//end if
}
at this point I guess I'm done thinking,Any answer/idea would be appreciated.
Here's a partial inspection of your code. I believe there is an issue debugging a 3 way merge sort with 4 values. You should use more values, such as 6 or 7.
Spaces not tabs for StackOverflow
I'll take a guess that the indentation is because you use tab characters in your code and pasted directly. You'll want to expand the tabs in your next post.
Precompiled Headers
Is your project huge? Does it significantly reduce the build time when you change a header or modify the source code?
I find that stdafx usually is more of a hassle and the time spent resolve defects it causes negates any potential savings by having a precompiled header.
Function prototypes should use named parameters
Can you tell the purpose of the different parameters in your declaration of merge and mergeSort?
Ambiguity breeds defects. 'nuff said.
Main function declared wrong.
The main function always returns an int to the operating system, always. The OS can ignore it.
This mechanism is so that script files can execute your program and test for errors.
Readability prevents defects
Invest in spaces around operators. The time saved by sacrificing spaces is negligible. The debugging time saved by having easy to read code is tremendous, especially when having other people review or inspect your code.
Use intermediate variables
Intermediate variables help clarify your program. They don't cost memory when you tell the compiler to optimize. During debugging, they can help show values during calculations.
The typical idiom for reading into a vector is:
int value;
cin >> value;
s.push_back(value);
The at method may have an overflow issue (or at least your not checking for out of bounds issues). The push_back method will cause the vector to expand as necessary.
Meaningful variable names reduces defects
The variable s has no meaning. Something like original_values or number_container are more descriptive. And again, variable name lengths have nothing to do with improving performance. Readable names help reduce the defects injected.
Not checking state of cin
If I enter "Lion" in response to your 2nd prompt, what will be in the 2nd slot of the array?
Don't trust the Users, they aren't perfect.
Don't clear the screen
It may contain useful data, such as the actual numbers entered. So when you are debugging, and want to know what the User actually typed in, it will be lost and gone forever.
Why cin.get twice?
You are asking the User for input without prompting. And twice. Bad Karma between your program and the User.
See cin.ignore if you want to ignore characters until a specific one is received. Something like this perhaps:
cout << "Paused. Press Enter to continue.\n";
cin.ignore(100000, '\n');
Magic numbers
In function mergesort, you use the numbers 2 and 3. Why? What's their purpose?
Redundant comments
Most programmers realize that the '/' character in a math expression is division. The comment is redundant.
Also, why divide by 3? It's a nasty number. Do you realize you are performing integer division and your product will be truncated? For example: 1/3 == 2/3 == 0.
USE A DEBUGGER
Lastly, a lot of your program's functionality can be verified easier and quicker by using a debugger. A debugger allows you to execute a statement and see the variable values. You can set breakpoints to stop execution at different places. It's a worthwhile educational investment, start now.
A "classic" 3 way merge sort merges runs 3 at a time, alternating between a source and destination array (or vector or list). The code needs to perform up to 3 compares in order to determine the "smallest" of 3 values from each of the 3 runs, then move the smallest value from it's corresponding run to the destination array. The code also has to handle the case where the end of a run is reached, leaving only 2 runs to merge, then the case where the end of the second run is reached, in which case the rest of the third run is moved to the destination array.
For a ram based sort, I'm not sure this is any faster than a normal 2 way merge. For an external sort, with multiple devices or very large read and writes, then a k way merge with k up to 12 or 16 will be faster.

A function that converts base 10 to binary using stacks to solve it

So I'm asked to write this function in C++ that converts a base 10 integer and prints the integer's binary equivalent
I should use a stack to solve the problem also I'm not allowed to use recursion in my function.
Here's what i think:
While doing the conversion i should start pushing the 1s and 0s into a stack accordingly , the order will be reversed (i think) so i will have to move them to another stack to have the right order after doing that i can start taking the top of the copied stack and print it then pop it to get the next number since the function is not a member function and i cant access the members randomly .
I need to know if my method is right and I'm not exactly sure how to do the conversion.
Here you go:-
#include<iostream>
#include<stack>
using namespace std;
int main()
{
int number;
cin>>number;
stack<int> binary;
while(number>1)
{
binary.push(number%2);
number /= 2;
}
cout<<1;
while(!binary.empty())
{
cout<<binary.top();
binary.pop();
}
return 0;
}
Tip:
Whatever recursion can do, loops can also do.
If you have an idea, always try to implement it first. You can still ask questions if you fail.

Stack Overflow error in recursive C++ function [duplicate]

This question already has answers here:
Does C++ limit recursion depth?
(6 answers)
Closed 9 years ago.
#include<iostream>
using namespace std;
int f()
{
static int count=0;
count++;
if (count>=5000)
return count;
return f();
}
int main ()
{
cout<<f();
return 0;
}
this function overflows the stack after the value of count exceeds 4800 can anybody tell how to resolve this issue ?
Don't use recursion - use a regular loop. Every time you call your f() method, you will occupy few words on the stack, and you will overflow it at some point.
Usually, there's way to increase stack size (depending on your system and/or compiler), but I don't want to recommend that (especially because it will overflow again, just with the value of count bigger than 4800).
Or just int f(){ return 5000; } would do.
Assuming you want to run recursively, you could turn off debug mode, then you'll succeed (as Visual Studio adds extra stuff on the stack to detect if you "clobber" the stack [it's how it can say "The stack around variable x was overwritten" or whatever the exact message is].
However, relying on being able to do LARGE number of calls recursively is a bad plan in general - at some point or another, it will still fall over. Whether that is 5000, 50000 or 500000 is just a matter of "how much stack-space does this function take". I'd say anything that doesn't have a natural limit of around 100 levels of recursion is a case of "you are solving the problem the wrong way". If you do have such large recursion levels, it's better to use a software stack (e.g. std::stack in C++), and save the crrent state on that stack, and restore it, using the software inside the function.
Running out of stackspace is one of the worst possible runtime problems, because there is really nothing you can do - there may be things you can do to print an error message or some such, but there is really no way to "give the process some more stackspace and continue". When a process runs out of memory or something similar, you can say "Ok, I won't allocate that, and give the user an nice error message saying 'I can't do this', and the nicely save the current state and exit, for example."
[And yes, you can increase the stack-size of your application, but that really should only be done as a true last resort, and only when you fully understand WHY you need such large stack - it's very often something else you're doing wrong if you need a bigger stack].
I'm assuming this is for an academic exercise to learn about recursion. (If it is not, please don't use recursion for this!)
A better way to write your function:
#include <iostream>
int f(int i)
{
if (i >= 5000)
{
return i;
}
else
{
return f(i + 1);
}
}
int f_alt1()
{
return 5000;
}
int f_alt2()
{
int i = 0;
for (; i <= 5000; ++i);
return i;
}
int main()
{
std::cout << f(0) << std::endl;
return 0;
}
This will still eat up far more runtime resources than returning the constant or incrementing in a loop, and you will need to increase your stack size if you increase the desired constant to a significantly larger number.

display multiple errors via bool flag c++

Been a long night, but stuck on this and now am getting "segmentation fault" in my compiler..
Basically I'm trying to display all the errors (the cout) needed. If there is more than one error, I am to display all of them.
bool validMove(const Square board[BOARD_SIZE][BOARD_SIZE],
int x, int y, int value)
{
int index;
bool moveError = true;
const int row_conflict(0), column_conflict(1), grid_conflict(2);
int v_subgrid=x/3;
int h_subgrid=y/3;
getCoords(x,y);
for(index=0;index<9;index++)
if(board[x][index].number==value){
cout<<"That value is in conflict in this row\n";
moveError=false;
}
for(index=0;index<9;index++)
if(board[index][y].number==value){
cout<<"That value is in conflict in this column\n";
moveError=false;
}
for(int i=v_subgrid*3;i<(v_subgrid*3 +3);i++){
for(int j=h_subgrid*3;j<(h_subgrid*3+3);j++){
if(board[i][j].number==value){
cout<<"That value is in conflict in this subgrid\n";
moveError=false;
}
}
}
return true;
}
If this is a chess board, then:
for(index=0;index<9;index++)
should be:
for(index=0;index<8;index++)
Or even better:
for(index=0;index<BOARD_SIZE;index++)
If you've got named constants, always use them in place of magic numbers.
check your indices. As you are using a fixed sized array, it might be an off-by-one error
To find out the exact line that is triggering your SEGFAULT, compile with the flag -ggdb (I'm assuming you are using GCC), and then run your program using gdb (using gdb ./name_of_the_program). When GDB starts up, use run to start the program. It will break at "main", and then execute continue. Let it run until it SEGFAULTs. Once it has segfaulted, execute backtrace (or, bt for short) to get a backtrace of the program execution. The backtrace should include the exact line that caused the SEGFAULT.
With the information that you get out of GDB, you should be able to debug your program. However, if you need more help than that, provide us with the output from backtrace so that we can be of more help.
1) Use this function instead of directly board[x][index], etc.:
const Square& GetSquare(
const Square board[BOARD_SIZE][BOARD_SIZE]&,
int x,
int y)
{
assert(x >= 0);
assert(x < BOARD_SIZE);
assert(y >= 0);
assert(y < BOARD_SIZE);
return board[x][y];
}
Test that you are on debug so that assert(false) gives an error message. Write assert(false), see the message, then delete this line. Without these assertions, I simply cannot trust your code.
2) Do not use magic numbers 9 and 3.
3) Take into account that int v_subgrid=x/3; may have a nonzero remainder, e.g., 7/3=2 and the remainder is 1. And 2/3=0. If this is what you want, ok. Just take it into account.
I expect your seg value might be in the following section... (as well as mentioned above (using 9 instead of BOARD_SIZE) for the proir two for-loops )...
for(int i=v_subgrid*3;i<(v_subgrid*3 +3);i++){
for(int j=h_subgrid*3;j<(h_subgrid*3+3);j++){
if(board[i][j].number==value){
cout<<"That value is in conflict in this subgrid\n";
moveError=false;
}
}
I would recommend you write some robust tests for functions such as yours (unit tests). Passing in values of X or Y that are set to BOARD_SIZE - 2 or above would mean indexing out of the array size of the board.
What I'm trying to get across is, code really need to be in place to stop indexing out of bounds,
hope this also helps,
Neil