word.exe has stopped working using recursion - c++

when I remove return in else section the code throw word.exe has stopped working
I tried to debug and when the base condition is true and 'i' start to decrement when 'i' is equal to 1 it throws the error
string o = "555";
string play(int i){
if(i == 3) return o;
else
return play(i+1);
}

You cannot remove the return statement.
Indeed, play() returns a string. So if the condition is true, you return the string o. But if you enter the else block, you also have to return a string, because the play(i+1) will return a string if its condition succeed, but nothing otherwise (except running another call). And you don't want to get nothing, you want to get back the resulting string.
In other words, when the child function returns a string, the current function needs to pass it to its parent and so on. If the child function condition succeeds and you missed the return statement, you will never pass this result to the parent and finally, you will return nothing at the top (Unexpected behaviour or error, honestly I didn't try).
And by the way, the code you are running is very dangerous. If the int passed in parameter is greater than 3, the recursion will run endlessly, adding play() calls until running out of memory.
I hope it answers your question :)

Related

C++ - Continuing a while loop upon exception

When an exception is encountered in C++, does the program automatically terminate upon catching it. Is there a way that ,if the exception was caught within a loop, I could just skip the rest of the loop and go straight to the next iteration?
There are a number of different ways to solve this problem.
Create a member function that checks whether a move is valid before making it. The calling code will need to call this function before calling advance, and only call advance if the move is valid.
Make the advance member function return a value indicating whether the player's position was advanced. The calling code will need to test the return value to decide whether to print the board or print a "try again" type of message.
Make the advance member function throw an exception if the move is invalid. The calling code will need to catch the exception.
There are lots of other ways to solve this problems.
Well first of all, if that snipped of code is EXACTLY how you copy-pasted it, it has some syntax errors. This is how it should be written:
int main() {
...
Person *p = new Person("Neo");
...
string in;
while(cin >> in) {
if (in == "q") {
break;
}
else if (in == /*One of the eight directions North ... Northwest*/) {
p->advance(in);
} //this bracket here ends the if. after the parentheses, nothing else will execute
else {
cerr << "Input one of the eight directions" < endl;
}
}
}
So yeah, if I understood correctly your problem, adding that closing bracket there should solve it. I hope this is what you needed and that it was helpful

c++ unless wrapper construct for flow control

I have a program part that works similar to the following:
X->updateA();
X->updateB();
X->updateC();
X->updateD();
Each function is supposed to return an integer indicating whether it ran successfully or not, say int ret_val=0 if successful and int ret_val=1 if not.
I am wondering if there exists any wrapper construct that processes each function consecutively as long as ret_val == 0. In my case it shall also call X->updateD(); regardless of the value of ret_val.
Right now I have:
int ret_val = 0;
ret_val = X->updateA();
if (ret_val == 0) ret_val = X->updateB();
if (ret_val == 0) ret_val = X->updateC();
X->updateD();
Which I think is not really readable. What I'd prefer is something similar to the while-loop, although it would have to check for the condition after each function call. Something along the lines of this:
int ret_val = 0;
unless(ret_val != 0)
{
ret_val = X->updateA();
ret_val = X->updateB();
ret_val = X->updateC();
}
X->updateD();
Is there any such construct?
You should use exceptions. Effectively they are an external control flow mechanism which means that you do not have to litter your regular code with error handling and manually propagate every error and check for errors on every call. With exceptions, your original code is perfectly valid as-is and the compiler generates code to check for errors and propagate them to the caller if one occurred.
You should store pointers to the functions you wish to invoke in a container, then iterate over the container. That way you can do whatever you like with the result, and it'll be the same for each function call, without having to repeat that logic n times.

Dereferencing a set iterator causes a seg fault

I'm trying to determine why the following code is throwing a segfault on line 10 (where we dereference upgradeIter).
bool UpgradeType::isAffected(const UnitType *unitType) const{
if(std::find(effects.begin(), effects.end(), unitType)!=effects.end()) return true;
// Check if the unit has any of the affected tags
std::set<string>::iterator upgradeIter;
for(upgradeIter = tags.begin(); upgradeIter != tags.end(); ++upgradeIter) {
std::set<string>::iterator unitIter;
for(unitIter = unitType->getTags().begin(); unitIter != unitType->getTags().end(); ++unitIter) {
string unitTag = *unitIter;
string upgradeTag = *upgradeIter;
if(unitTag == upgradeTag) return true;
}
}
return false;
}
The context is that UpgradeType has "tags" (just a set of strings). Units also have tags. If a unit shares at least one tag with the upgrade, then the unit is affected by the upgrade.
I don't see any reason why the mentioned line would crash. It seems to me that there is no circumstances under which the iterator could be invalid.
In other parts of the code that display the contents of tags (used in very similar ways), the output is as expected.
EDIT: I've just found out that unitType->getTags().size() is 0. So I don't understand why the body of the for loop is even executed. unitIter != unitType->getTags().end(), however, is evaluating to true. This seems off.
I managed to find a solution to this with the help of Yggdrasil on this site (which also means that Matt McNabb in the question's comments was correct). Quoting his post below:
As someone more or less mentioned on stackoverflow: Change getTags() to return a reference, not a value/copy.
const set &getTags() const {return tags;}
Be aware that the return type is const, so use a const iterator.
Not sure if that's all, but you don't want a (deep) copy there, for sure. The iterator gets out of bounds because you check against the end of a different set. Every call to getTags() gets its own copy.

c++:return statement behaving weirdly

Here is an outline of the code containing the relevant part of my code.
Inside the empprint function i call a bfs print function, which calls itself recursively till its done printing everything that needs to be printed, after which its supposed to return me back to empprint function. But the return statement in bfsprint doesn't take me back to empprint.
One possible reason I can think of is that bfsprint calls itself recursively so it will only return to the last bfsprint method that called it instead of empprint function but it doesnt seem to solve my problem. I m stuck up with a code whose execution doesnt terminate.
void node::empprint(node* myroot)
{
//do something
bfsprint(c);
cout<<"pt 5"; //this cout is not reached
return;
}
void node::bfsprint(Linklist<node*> noddy)
{
// lot of code to implement breadth-first search. No issue
if(c.getHead()==NULL) cout<<"1" //this does print 1 to output
if(c.getHead()==NULL) return; //I think this should send me back to empprint
// and print "pt 5" on output but program hangs.
// instead of this happening
bfsprint(c);
}
If anybody thinks this might be influenced by other code in the method , I will add it but I dont think its the case.
If your call stack looks like:
node::empprint
node::bfsprint
node::bfsprint
then returning from the final call will result in
node::empprint
node::bfsprint
So your still N calls deep away from getting back to node::empprint.
You could set a bool in the class to return back out, but thats a bit hacky..
void node::bfsprint(Linklist<node*> noddy)
{
if ( something ) { m_unwindstack = true; }
// setting the bool to force returning early/stop recursion once m_unwindstack is true to get back to empprint
if ( m_unwindstack ) { return; }
}
Edit: By the way if you're doing anything with Linklist you'll never seen the changes since your passing a copy of the data. You should pass a reference Linklist&.
Also Linklist seems like your own class? So if you don't use a reference then be sure its copyable otherwise bad things will happen.

do i need a break after return in my function?

this is a function in my code:
bool same_community(string s1, string s2)//check if student 1 & student 2 are in the same community
{
for(int i=0;i<number_of_communities;i++)
if(community[i].contains(s1) && community[i].contains(s2))
{
return true;
break;
}
return false
}
is the break after return true needed?
No. It's dead code and will very likely be removed by your compiler's optimizer. Remove it, since it reduces your code's readability.
No, the return statement is enough to exit the loop.
No. The break is not needed. The return is enough.
No, you don't need to. The return expression makes the execution flow leave the function. Anything after return won't get executed.
No you don't need to use break. It is used to terminate a loop early, but return (within a subroutine) will also terminate any loop it is inside of. Anything that follows return is dead code.