control reaches end of non-void function (only on particular IDEs) - c++

int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
if(k==n1)
return count;
if(k>n1)
return --count;
}
This is a function that returns the largest power of two less than n. When I run it in my ubuntu terminal (g++ 4.8.4), it works fine. But when I am running it on www.hackerrank.com, it gives an error(control reaches end of non void function). The problem is, I participate in many contests on this website and I have come across this problem multiple times.
Please tell if you know how I can fix it.

You can use else if statement like this:
int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
else if(k==n1)
return count;
else // Eliminate compiler errors (warnings)
return --count;
}
or as said #juanchopanza:
int findpow(int n1,int k, int count){ //while calling, k=1, count=0
if(k<n1)
return findpow(n1,k*2,count+1);
if(k==n1)
return count;
// Eliminate compiler errors (warnings)
return --count;
}
It will do the same thing as your code, but will not give a doubt to compiler that can be no return points from function.

'control reaches end of non void function' is a warning not an error, it's safe to ignore in this case but if you want to suppress the warning there are multiple ways:
put a return after the last condition
as Mykola suggested restructure the conditions to be explicit
set the -Wno-return-type flag

Related

Errors in Hackerrank compare the triplets code

I was doing the hackerrank triplet sum question and I found these errors but I dont know why these errors are coming. Can someone please give a little more insight about it and if possible link a video about the topics I should read in order to atleast get the code correct.
The code
#include <iostream>
using namespace std;
int compareTrip(int a[],int b[])
{
int i=0,result1=0,result2=0;
for(i=0;i<3;i++)
{
if(a[i]>b[i])
result1++;
if(a[i]<b[i])
result2++;
else {
return 0;
}
}
}
int main()
{
int i,a[3],b[3];
for(i=0;i<3;i++)
{
cin>>a[i];
}
for(i=0;i<3;i++)
{
cin>>b[i];
}
compareTrip(a[], b[]);
}
The Errors
Solution.cpp:30:19: error: expected primary-expression before ‘]’ token
compareTrip(a[], b[]);
^
Solution.cpp:30:24: error: expected primary-expression before ‘]’ token
compareTrip(a[], b[]);
^
Solution.cpp: In function ‘int compareTrip(int*, int*)’:
Solution.cpp:18:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
static List<Integer> compareTriplets(List<Integer> a, List<Integer> b) {
List<Integer> points=new ArrayList<Integer>(2); ;
int apoint=0,bpoint=0;
for(int i=0;i<3;i++)
{
if(a.get(i)>b.get(i))
{
apoint++;
}
else if(a.get(i)<b.get(i))
{
bpoint++;
}
else
{
}
}
points.add(0,apoint);
points.add(1,bpoint);
return points;
}
These first two errors occur because the compiler thinks you're trying to redefine the arrays a and b, which you've already initialized the at the beginning of main. When you call compareTrip() , you just need to pass in the names of those arrays as the two arguments.
The error control reaches end of non-void function indicates that there is no return value at the end of the function at line 18. So you have a set of if/else statements in compareTrip() , but it's possible that you might get two arrays of integers where there is no match between a and b, and the function does not account for this condition. If this edge case happens, we'd find ourselves in an infinite loop, because the function would leave the for statement and never return. Because the return value is an int, you want to include a return statement outside of the for loop, before the final closing bracket },to avoid an infinite loop.
You start learning more about C++ and its basic syntax through online courses like https://www.learncpp.com/,, https://www.sololearn.com/Course/CPlusPlus/, and https://www.codecademy.com/learn/learn-c-plus-plus. I believe the first two are free, and the third lets you start with a free trial. Happy learning!
You should use compareTrip(a,b); instead of compareTrip(a[], b[]); as you are passing argument.
Your main function should return some value as it is interger type int main().
hope it helps.

Persisting variables outside scope of a function

This is part of a debugging assignment that I've been stuck on for days. I'm not as much looking for an answer as much as I'm looking for where to look to find the answer.
I have a function that takes an int as a parameter, and the test uses that function to calculate the sum of the range (0,n]. My problem is that I am new to C++ and have exhausted my knowledge of where to look to solve this. Any help would be greatly appreciated.
Also, it goes without saying that I cannot modify the test file.
Header.h
bool getNum(int n);
Header.cpp:
bool getNum(int n)
{
n = n + 1;
if (n < 10)
{
return true;
}
else
{
return false;
}
}
Test.cpp
int n = 0;
int sum = 0;
while (getNum(n) && n)
{
sum += n;
}
CHECK(sum == 45);
My problem is that I have no way of getting n to be true to pass the logical &&, so the test never visits the inside of the while loop.
You can change the value of an argument to a function, by taking that argument as a reference:
bool getNum(int &n) // note the reference parameter
{
// changes to n are visible to the caller of this function
}
You have to change the declaration of getNum to match as well, of course.
Note that there is no change to the calling code.
Here's a demo of a working example.

Solution for a problem using vectors in c++ shows 𝒓𝒖𝒏𝒕𝒊𝒎𝒆 𝒆𝒓𝒓𝒐𝒓 when submitted but runs fine when the same input is run using custom input

Recently I was solving this problem on interviewbit.com - https://www.interviewbit.com/problems/merge-intervals/.
I solved the problem using vectors and performing operations on vectors
Here is my code:
vector<Interval> Solution::insert(vector<Interval> &intervals, Interval newInterval)
{
int n=intervals.size(),leftfound=0,rightfound=0,count=0;
if(n==0) //for the case when intervals vector is empty
{
intervals.push_back(newInterval);
return intervals;
}
int t=0;
if(newInterval.end<newInterval.start) //if(start>end) swap
{
t=newInterval.start;
newInterval.start=newInterval.end;
newInterval.end=t;
}
if(newInterval.start>intervals[n-1].end) //if the newInterval succedes every other
{
intervals.insert(intervals.end(),newInterval);
return intervals;
}
if(newInterval.end<intervals[0].start)//if the newInterval precedes every other element
{
intervals.insert(intervals.begin(),newInterval);
return intervals;
}
auto left=intervals.begin(),right=intervals.begin(); //just initialising with something
auto it=intervals.begin() ; // iterator for loops
while((*it).start<newInterval.start&&it!=intervals.end()) //*it is dereferencing the iterator to
it++; //get the element of vector "intervals" at that index
it--; // decrementing it to reach the desired interval
if((*it).start<=newInterval.start&&(*it).end>=newInterval.start)
{
leftfound=1;left=it;
}
else
left=it+1;
it=left;
while((*it).end<newInterval.end&&it!=intervals.end())
it++;
if((*it).start<=newInterval.end&&(*it).end>=newInterval.end)
{
rightfound=1; right=it;
}
else
right=it-1;
if(right-left==-1&&leftfound==0&&rightfound==0)// this if will be true in cases like:
intervals.insert(left,newInterval); //intervals=[(1,2),(8,10)] and newInterval=(4,6)
else //in every other case this else will execute
{
if(leftfound==0)
(*left).start=newInterval.start;
if(rightfound==0)
(*left).end=newInterval.end;
else (*left).end=(*right).end;
}
left=left+1;
intervals.erase(left,right+1);
return intervals;
}
The interviewbit.com platform(IDE) requires to only complete the function given as mentioned in the problem.
NOTE: You only need to implement the given function. Do not read input, instead use the arguments to the function. Do not print the output, instead return values as specified. Still have a doubt? Checkout Sample Codes for more details.
I need to implement this:
vector<Interval> Solution::insert(vector<Interval> &intervals, Interval newInterval) { }
Also the Interval structure is defined as :
struct Interval {
int start;
int end;
Interval() : start(0), end(0) {}
Interval(int s, int e) : start(s), end(e) {}
};
Now this solution runs fine when tested using the test button on the site. After that when I press submit it shows the following error:
click to see error. When I run the same test case (for which the error was encountered) using custom input the code runs fine and gives the expected output. I can't seem to find what the problem is. I suspect it might be because of the erase function since in the error it shows free(), but I am not even remotely sure.
Also, I ran the code on ideone.com adding the structure and main function in the code and it runs absolutely fine.
intervals.insert(left,newInterval);
std::vector::insert invalidates all existing iterators to the contents of the vector. Immediately afterwards:
left=left+1;
intervals.erase(left,right+1);
The left and right iterators, to the same vector, are no longer valid at this point, and using them is undefined behavior.
This may or may not be the only bug in the shown code. The broken indentation makes the shown code hard to read and follow; but this is one definite bug in the shown code, that's likely the reason for the undefined behavior, and the crash.

Max-heap implementation

Following code for max-heap implementation
#include<iostream>
#include<math.h>
using namespace std;
#define maxn 1000
int x[maxn];
int parent(int i){
return int(i/2);
}
int left(int i){
return 2*i;
}
int right(int i){
return 2*i+1;
}
void max_heap(int x[],int i,int size){
int largest;
int l=left(i);
int r=right(i);
if (l<=size && x[l]>x[i]){
largest=l;
}
else
{
largest=i;
}
if (r<=size && x[r]>x[largest]){
largest=r;
}
if (largest!=i) { int s=x[i];x[i]=x[largest];x[largest]=s;}
max_heap(x,largest,size);
}
int main(){
x[1]=16;
x[2]=4;
x[3]=10;
x[4]=14;
x[5]=7;
x[6]=9;
x[7]=3;
x[8]=2;
x[9]=8;
x[10]=1;
int size=10;
max_heap(x,2,size);
for (int i=1;i<=10;i++)
cout<<x[i]<<" ";
return 0;
}
When I run it, it writes such kind of warning:
1>c:\users\datuashvili\documents\visual studio 2010\projects\heap_property\heap_property\heap_property.cpp(36): warning C4717: 'max_heap' : recursive on all control paths, function will cause runtime stack overflow
Please tell me what is wrong?
The message tells you exactly what's wrong. You haven't implemented any checks to stop the recursion. One smart compiler.
max_heap function doesn't have base case, i.e., a return statement. You are just recursively calling the function but never saying when to break another successive call to the max_heap.
Also, in your example you are just calling the function with out satisfying any condition. Usually recursion is done or not done when a case is satisfied.
please tell me what is wrong?
Another problem that I see is that the size of your array x is 10. But the indices that you are using to set values are 1-10.
Put
max_heap(x,largest,size);
inside last check, like this:
if (largest!=i)
{
int s=x[i];
x[i]=x[largest];
x[largest]=s;
max_heap(x,largest,size);
}
and you're done!
There are many other problems with your code, but to answer your specific question, above change would do!

Simple recursion question

Let's say we have a simple recursion like.
int x(int a){
if(a<10)
x(a+1);
else
!STOP!
b++;
return b;
}
Globaly:
int b=0;
In main we could have something like this:
int p=x(1);
Is there any way to stop the recursion so that the p will be 0, this means that "b++" will never be executed.
I'll be grateful if you could tell me some expresion to put instead of the !STOP!
But, I don't want anything like this, I just want to stop the recursion, like break; does in a while() loop...:
int ok=0;
int x(int a){
if(a<10)
x(a+1);
else
ok=1;
if(ok==0)
b++;
return b;
}
If there's anything unclear about the question, just ask.
Why wouldn't you do this?
int x(int a){
if(a<10) {
x(a+1);
b++;
}
return b;
}
The thing is, though, you're modifying a global in a recursive routine, which is not especially threadsafe and pretty sloppy. You're returning a value that is always ignored except by the top level caller. You're also doing something that is better off being done in a loop (but I assume that your actual case is bigger than this, or you're a student).
You can't really "break" the recursion - returning unwinds well enough. In oldey-timey C you might use setjmp/longjmp (and all its perils - in other words, DON'T), and in C++ you might use try/catch/throw, which will unwind the stack as well.
How about like this?
int x(int a){
if(a>0 && a<10)
x(a+1);
b++;
return b;
}
The only thing in C++ that will unwind the stack like that is an exception. There's also setjmp()/longjmp(), but those should never be used in a C++ program. Any other construct can at most return from the current function.
How about returning?
int x(int a){
if(a<10)
x(a+1);
else
return b;
b++;
return b;
}
I think this looks a bit better
int x(int a){
if(a<10)
x(a+1);
else
return b;
return ++b;
}
EDIT:
I think You could use exception mechanism to unwind the stack and get to the point of first invocation, but it's safe after entering main(). Referencing b in x, given the code:
int b = 0;
int p = x(1);
suggests that x is used for initialization of some global variable and may be executed before main(). How about using some helper function that wraps invocation of x in a try - catch block and throwing an exception in the place of |STOP|?
If you're trying to declare b in main(), and use b in x() then there's something wrong already to begin with. Instead, make b into a local variable by passing it as a parameter to x, and returning a modified version of b.
int x(int a, int b){
if(a<10)
return x(a+1,b+1);
else
return b;
}
I'm not a big fan of using an Exception for control. I don't expect you'll save many cycles by using Exceptions instead of if/return statements. You're going to have to test your boundary conditions anyway before throwing an Exception.
You can however simplify the problem a bit by changing the return type of the function.
bool x(int a){
if(ok) //Exit early before next call up?
return true;
if(a<10){
if(x(a+1)) //Have we been told to exit early?
return true; //Yes
b++; //Do some work
if(ok) //Exit early in the next call down?
return true;
}
return false; //Normal Exit
}