I believe there is a simple solution to my issue, but my brain is too fried to think right now.
Inside my main function I have a function we will call "Function1". In "Function1" I call another function that verifies the data in "Function1", lets call this "Function2". In order for "Function2" to do its job well, it needs to call "Function1" again. This is obviously how I am getting an infinite loop of "Function1" and "Function2" repeatedly calling each other. I need to create method for tracking this so I can stop the loop after the first pass of Main --> Function1 --> Function2 --> Function1 --> End, but my implementation keeps failing.
I greatly appreciate any help and guidance.
You need to pass in a level counter to function1. On the first call the level is 0. If the level is 0, it can call function2. If it > 0 then do not call function2.
When function2 calls function1, it sets the level to 1 (or increases it).
This is how you do recursive calls. You can, of course, change the end condition to something else as needed (instead of just 0 and 1).
You could set a counter integer, and only run Function2 when the counter is less than 1 (or however many times you'd like the loop to iterate before breaking out).
For example (pseudocode):
int count;
Function1{
...
while(count < 1){
Function2{
.... //Function2 code
count++;
}
}
.. //any code from Function1 that should run after Function2
}
(Note, you could also do this with a boolean if you'd like - I prefer the integer approach, as you can change the number of iterations before breaking out fairly easily)
Related
I am new at recursive functions.
int display(int num) {
if(num) {
display(num-1);
}
else {
return 0;
}
printf("\t%d", num);
}
When I run display(5), i can get "1 2 3 4 5" output as i want.
BUT:
When I add another function in this code and make some changes on the display() function and run the display(5) command it gives no output.. Here is the other code:
int bunnyEars2(int line) {
if(line == 0) {
return 0;
}
if(line % 2 == 1) {
return 2 + bunnyEars2(line-1);
}
else {
return 3 + bunnyEars2(line-1);
}
}
int display(int n) {
if(bunnyEars2(n)) {
display(bunnyEars2(n-1));
}
else {
return 0;
}
printf("\n%d", bunnyEars2(n));
}
I want to take bunnyEars2(1), bunnyEars2(2), bunnyEars2(3), bunnyEars2(4), bunnyEars2(5) outputs from display(5) command. But it gives no output. Can you help me out with this?
When you call display(5) it calls display(bunnyEars2(5)) which is display(12) => infinite loop
display(n) calls display(bunnyEars2(n-1)) and for every n>=2, bunnyEars2(n-1) > n so that you will get an infinite loop.
Other people have already given the reason for why this code is causing issues so I'll go into how to potentially look the causes of issues like this in the future.
When writing a recursive function, It is important to identify the various cases for your function. Each recursive function will have a set of cases which cause the function to call itself (recursive cases) and a set of functions in which the function will not call itself (base cases). In the case of the display function given in the first example. The recursive case is -- num has a non zero value, and the base case is -- num has a value of 0. A recursive function will only cease recursing if a function call hits a base case causing the recursive function calls to resolve rising up the call stack. Under any circumstance, any call to a recursive function does not lead a call of the function resulting in the execution of the base case, the call to the function will not resolve resulting in infinite recursion.
This infinite recursion is occurring in your second version of the display function. Look closely at the recursive case of your second display function.
if(bunnyEars2(n)){
display(bunnyEars2(n-1));
}
How would the value of bunnyEars2(n-1) compare to the value of n? Examine whether this recursive case will result in a calling of the function that executes a base case.
If you have access to a debugger and know how to use it, try stepping through the function and see what path it takes through the code. If you do not have access to a debugger, get some paper and a pencil and walk through the execution of your function by hand. This should give you a better idea about what your code is doing and how a problem might arise.
I have to make the code of a coffee dispenser in C.
I already have everything done and I just need to know how I can keep on running my "main" function until a certain condition is met (for example: util the machine can give no more change).
How can I achieve this?
I don't think you need a recursive main or for that matter any recursive function call at all for this. All you need is an infinite loop.
int main()
{
while (1) /* Infinite Loop */
{
... do stuff
if (condition is met)
break;
}
}
I see this way too often in the codebase I'm currently working in:
int obtained_number = 5;
char *answer = tpalloc(15);
sprintf(answer, "num:%d", obtained_number);
tpreturn(TPSUCCESS, 0, answer, answerSize, 0);
tpfree(answer);//why?
According to the documentation:
tpreturn() acts like a return statement in the C language (that is, when tpreturn() is called, the service routine returns to the BEA Tuxedo system dispatcher).
If this is so, I guess the service finishes at that point and tpfree() is never called. When the service is called again, it starts in the main method again, instead of where the execution finished last time.
Is this correct? Should I report this unnecesary use of tpfree()?
tpreturn() actually performs longjmp() and no code after tpreturn() is executed. When the service is called again, it starts from the beginning of service function.
In your case it means that tpfree() is never executed and it should not - tpreturn() takes care of buffer you pass to it (releases, caches for the next call, etc.)
What is worse for C++ code
std::string obtained_str = "5";
char *answer = tpalloc(15);
sprintf(answer, "str:%s", obtained_str.c_str());
tpreturn(TPSUCCESS, 0, answer, answerSize, 0);
destructor for obtained_str will not be called and you will have a memory leak.
First this gets triggered:
if ((temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) | (temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit))
activateAlarm(channelID);
Activate alarm is triggered, then from there:
void activateAlarm(int channelID);
{ while (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit || temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit)
{
logSubsystem(temperatureChannel[channelID].currentTemperature);
}
}
Then alarm screen is triggered with following case:
int logSubsystem(int currentTemperature)
case 'F': //if user input is 'F'
case 'f': //if user input is 'f'
currentTemperature--;
printf("your current exceeded temp is %i\n \n", currentTemperature);
if (currentTemperature <= 100 || currentTemperature >= 50);
compareLimit();
break; //exits loop
How do I set up this function so that if the user decrements with F and gets the current temperature to below the limit (<100, or >50), then it will return back to the compareLimit function and the requirement for the high limit/low limit triggered state will be FALSE, returning the program to its original pre-alarm state?
I think you would benefit considerably from thinking a lot about how your program flows. Right now, what I can deduce of your program flow is:
You have an outer loop that checks the temperature, on at least one channel ID. Inside that loop, you have the if statement you first showed us.
Then activate alarm does some other stuff, but loops until the temperature goes down, calling logSubsystem.
logSubsystem then presumably gets some kind of user input, and from there, you want it to call to your initial function, presumably called prepare limit.
The problem with this is that none of these functions ever complete. They all call each other, and you'll eventually get a stack overflow. Nice, since that's the name of this site, but not something you want to aspire to.
What you basically need is a state machine. You need something that keeps track of values, looks at those values, and calls functions that return that operate on those values. There should only be one loop, and it should do all the control of what happens based on what those values are. The good news is, you have all of this in place already. temperatureChannel is keeping track of the values for you, and you have while loops a-plenty.
Let me give you my suggestion of the way I suggest your program should flow:
bool checkTemperatureValuesOutOfRange(int channelID) {
// this is just a convenience, to make the state machine flow easier.
return (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) || // note the || not just one |
(temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit);
}
void actOnUserInput() {
char input = // ... something that gets a user input. It should check if any is available, otherwise return.
switch (input) {
case 'F':
case 'f':
temperatureChannel[channelID].currentTemperature--;
break; // This doesn't exit the loop - it gets you out of the switch statement
}
void activateAlarm(int channelID) {
// presumably this does something other than call logSubsystem?
// if that's all it does, just call it directly
// note - no loop here
logSubsystem(channelID);
}
void logSubsystem(int channelID) { // Not the current temperature - that's a local value, and you want to set the observed value
// I really think actOnUserInput should be (an early) part of the while loop below.
// It's just another input for the state machine, but I'll leave it here per your design
// Presumably actually logs things, too, otherwise it's an unnecessary function
actOnUserInput();
}
while (TRUE) { // this is the main loop of your function, and shouldn't exit unless the program does
// do anything else you need to - check other stuff
// maybe have a for loop going through different channelIDs?
if (checkTemperatureValuesOutOfRange(channelID)) {
activateAlarm(channelId);
// do anything else you need to
}
I'm sure you can see lots of differences between your code and mine. Here are some key things to consider:
All the functions now return. The master while loop calls functions that check status, and calls function that change status.
I would highly suggest acting on the user input as part of the master while loop. It's just another input to the state machine. Get it, act on it, and then check your statuses. You presumably need to have some input from the user, otherwise you'll never get in a bad state in the first place.
Right now, activate alarm happens every time. With the code you showed, that's fine - because logSubsystem was all that was being called. If you only want the alarm to ring once, keep a boolean tracker inside temperatureChannel[channelId] that says if the alarm rang, set it true within activateAlarm, and then reset it to false based on the return value of checkTemperatureValuesOutOfRange.
Rather than leaving yourself in the activateAlarm/logSubsystem area, you return each time, and check your values each time to see if you're still there. This is the key point - your functions should be fast, and not monopolize your processor. Make each function do just one sort of thing, and have all the control come from within the master loop.
I made a lot of changes to your code, and I don't know if you're allowed to make all of them, but you'll need something similar to this. It's much more robust, and gives you room to grow all around.
I have a function with an absurd number of return points, and I don't want to caveman each one, and I don't want to next through the function. Is there any way I can do something like finish, except have it stop on the return statement?
You can try reverse debugging to find out where function actually returns. Finish executing current frame, do reverse-step and then you should stop at just returned statement.
(gdb) fin
(gdb) reverse-step
There is already similar question
I think you're stuck setting breakpoints. I'd write a script to generate the list of breakpoint commands to run and paste them into gdb.
Sample script (in Python):
lines = open(filename, 'r').readlines()
break_lines = [line_num for line_num, line in enumerate(lines) if 'return' in line and
line_num > first and line_num <= last]
break_cmds = ['b %s:%d' % (filename, line_num) for line_num in break_lines]
print '\n'.join(break_cmds)
Set filename to the name of the file with the absurd function, first to the first line of the function (this is a quick script, not a C parser) and last to the number of the last line of the function. The output ought to be suitable for pasting into gdb.
Kind of a stretch, but the catch command can stop on many kinds of things (like forking, exiting, receiving a signal). You may be able to use catch catch (which breaks for exceptions) to do what you want in C++ if you wrap the function in try/finally. For that matter, if you break on a line inside the finally you can probably single-step through the return after that (although how much that will tell you about where it came from is highly dependent on optimization: common return cases are often folded by gcc).
How about taking this opportunity to break up what seems to be clearly a too-large function?
This question's come up before on SO. My answer from there:
Obviously you ought to refactor this function, but in C++ you can use this simple expedient to deal with this in five minutes:
class ReturnMarker
{
public:
ReturnMarker() {};
~ReturnMarker()
{
dummy += 1; //<-- put your breakpoint here
}
static int dummy;
}
int ReturnMarker::dummy = 0;
and then instance a single ReturnMarker at the top of your function. When it returns, that instance will go out of scope, and you'll hit the destructor.
void LongFunction()
{
ReturnMarker foo;
// ...
}