C - Manage call stack in recursive methods - c

I am new here and I have a problem that's bugging me.I am a beginner so please don't laugh at me.
I want to make recursive quicksort work on a large number of elements,let's say 100000.I know this will cause the stack to overflow.I have been googling for the past few days trying to find a way to manage the call stack.I can't really find a good source of information.
My ideea is to remove the return adress of each recursive call,except the last one,which will return to the first function call.I don't know if that is possible or if it is another solution for this problem.
P.S. : I want to keep the quicksort recursive.
Sorry if my problems looks silly,but i sould appreaciate any pertinent answer.
Sorry for my bad English.
Thank you!

The standard way to solve the issue of running out of stack space with recursive algorithm is to implement it iteratively instead.

Please note that 100000 items in an array is nothing; this will only lead to nested calls 17 functions deep:
$ echo "l(100000)/l(2)" | bc -l
16.60964047443681173951
That's log(N)/log(2) -- the log(2) is to convert it to log base 2.
Any platform that supports recursive function calls will almost certainly be able to handle 17 nested calls.

If stack space is a problem but memory in general isn't, you can easily convert a recursive implementation into an iterative one by using your own heap-allocated stack. That is, instead of making a recursive function call, push the arguments you care about onto your own stack data structure. You then can iterate over your stack and process each set of arguments.

it sounds like you're trying to do tail recursion, which has been discussed here;
Tail recursion in C

Related

Is there a maximum number of repetition when using recursion?

I m trying to make a sudoku solver,with basic knowledge,using recursion.It solved sudoku puzzles i entered as long as the number of repetition is less than 3485/3500.Every time it fails it fails somewhere around that number.So i was wondering is there a threshold or is it my mistake?
Each call takes some stack space. When you call things recursively, the first call is still going on while the second one starts, so you are using stack space for 2 calls. If call#2 makes call#3 then your stack contains 3 calls and so on.
The recursion limit is based on how much stack you have.

My Simpler Dead-code Remover

I am doing a stimulation of dead-code remover in a very simpler manner.
For that my Idea is to,
Step 1: Read the input C-Program line by line and store it in a doubly linked-list or Array.(Since deletion and insertion will be easier than in file operations).
Doubt:Is my approach correct? If so, How to minimize traversing a Linked-List each time.
Step 2: Analyzing of the read strings will be done in parallel, and tables are created to maintain variables names and their details, functions and their calls,etc.,
Step 3: Searching will be done for each entries in the variable table, and the variables will be replaced by its that time's value(as it has).
(E.g.)
i=0;
if(i==3) will be replaced by if(0==3).
But on situation like..
get(a);
i=a;
if(i){}
here,'i' will not be replaced since it depends on another variable. 'a' will not be replaced since it depends on user input.
Doubt: if user input is,
if(5*5+6){print hello;} ,
it surely will be unnecessary check. How can i solve this expression to simplify the code as
{
print hello;
}
Step 4: Strings will be searched for if(0),while(0) etc., and using stack, the action block is removed. if(0){//this will be removed*/}
Step 5:(E.g) function foo(){/**/} ... if(0) foo(); ..., Once all the dead codes are removed, foo()'s entry in the function table is checked to get no.of.times it gets referred in the code. If it is 0, that function has to be removed using the same stack method.
Step 6: In the remaining functions, the lines below the return statements (if any) are removed except the '}'. This removal is done till the end of the function. The end of the function is identified using stack.
Step 7: And I will assume that my dead-free code is ready now. Store the linked-list or array in an output file.
My Questions are..
1.Whether my idea will be meaningful? or will it be implementable? How
can I improve this algorithm?
2.While i am trying to implement this idea, I have to deal more with string
manipulations rather than removing dead-codes. Is any way to reduce
string manipulations in this algorithm.
Do not do it this way. C is a free-form language, and trying to process it line-by-line will result in supporting a subset of C that is so ridiculously restricted that it doesn't deserve the name.
What you need to do is to write a proper parser. There is copious literature about that out there. Find out which textbook your school uses for its compiler-construction course, and work through that -- or just take the course! Only when you've got the parser down should you even begin to consider semantics. Then do your work on abstract syntax trees instead of strings. Alternatively, find an already written and tested parser for C that you can reuse (but you'll still need to learn quite a bit in order to integrate it with your own processing).
If you end up writing the parser yourself, and it's only for your own edification, consider using a simpler language than C as your subject. Even though C at is core is fairly compact as languages go, getting all details of the declaration syntax right is surprisingly tricky, and will probably detract you from what you're actually interested in. And the presence of the preprocessor is an issue in itself which can make it very difficult to design meaningful source-to-source transformations.
By the way, the transformations you sketch are known in the trade as "constant propagation", or (in a more ambitious variants that will clone functions and loop bodies when they have differing constant inputs) "partial evaluation". Googling those terms may be interesting.

What are some good ways of implementing tail call elimination?

I've written a small Scheme interpreter in an unholy mix of C/C++, but I have yet to implement proper tail calls.
I am aware of the classic Cheney on the MTA algorithm, but are there other nice ways of implementing this? I know I could put the Scheme stack on the heap, but that would still not be proper elimination, as the standard says one should support an unlimited number of active tail calls.
I've also fiddled with longjmps, but so far I think it'll only work well for non-mutual recursive tail calls.
How do the major C-based Schemes implement proper tail recursion?
Simpler than writing a compiler and VM is to registerize and trampoline your interpreter. Since you have an interpreter and not a compiler (I assume), you only need a couple straightforward transformations to get proper support for tail calls.
You'll have to first write everything in continuation-passing style, which may be weird to think about and do in C/C++. Dan Friedman's ParentheC tutorial steps you through transforming a high-level, recursive program into a form that is machine-translatable to C.
In the end, you'll essentially implement a simple VM where instead of using regular function calls to do eval, applyProc, etc., you pass arguments by setting global variables and then do a goto to the next argument (or use a top-level loop and program counter)...
return applyProc(rator, rand)
becomes
reg_rator = rator
reg_rand = rand
reg_pc = applyProc
return
That is, all of your functions that normally call each other recursively are reduced to a pseudo-assembly in which they are just blocks of code that don't recur. An top-level loop controls the program:
for(;;) {
switch(reg_pc) {
case EVAL:
eval();
break;
case APPLY_PROC:
applyProc();
break;
...
}
}
Edit: I went through the same process for my hobby Scheme interpreter, written in JavaScript. I took advantage of a lot of anonymous procedures, but it might help as a concrete reference. Look at FoxScheme's commit history starting from 2011-03-13 (30707a0432563ce1632a) up through 2011-03-15 (5dd3b521dac582507086).
Edit^2: Non-tail recursion will still consume memory, even if it's not in the stack.
Without knowing what you have, I'd say the easiest (and most enlightening) way to do it is to implement the scheme compiler and VM from Dybvig's "Three Implementation Models for Scheme".
I've done it here in Javascript (a copy of Dybvig's PDF is there too): https://github.com/z5h/zb-lisp
check src/compiler.js: compileCons, and the implementation of the "op codes" in src/vm.js
If you are interested in implementation techniques of interpreters, there
is no way around the book "LiSP - Lisp in Small Pieces" by Christian Queinnec.
It explains all aspects of implementing a Scheme system very thoroughly with
complete code. It is a wonderful book.
http://www.amazon.com/exec/obidos/ASIN/0521562473/qid=945541473/sr=1-2/002-2995245-1849825
But don't forget to check out the papers on ReadScheme.org.
The section
Compiler Technology/Implementation Techniques and Optimization
http://library.readscheme.org/page8.html
has quite a few papers on tail call optimization.
Among others you will find a link to Dybvig's thesis (a classic),
which is very well written. It explains and motivates everything in
a very clear manner.

Registry Search

I am trying to use C/C++ (Preferably C) to enumerate the entire Windows registry, I was using recursion to do this but I keep running into stack overflows, which i understand but im unable to think of anyway to do this without recusion.
Advice on how to do this without recursion would be great, thx.
As long as your recursion is just once per level of subkey, I don't see why this should overflow the stack. Sure the Windows registry is a nightmare, but I don't think its keys hierarchies are thousands of levels deep.
I suspect you're using some giant arrays on the stack, which is a bad idea in general but especially with recursion. Try allocating any large data you need with malloc instead.
A bread-first search would be an obvious possibility. The basic idea is to use a queue of places to search. Start by putting the root into the queue, then repeat the following steps until the queue is empty:
Get an item from the queue.
Enumerate its contents.
Add any links it contains to the queue.
...where "links" would be "subdirectories" for a file system, "subkeys" for the registry, etc.

To find all possible permutations of a given string

This is just to work out a problem which looks pretty interesting. I tried to think over it, but couldn't find the way to solve this, in efficient time. May be my concepts are still building up... anyways the question is as follows..
Wanted to find out all possible permutation of a given string....... Also, share if there could be any possible variations to this problem.
I found out a solution on net, that uses recursion.. but that doesn't satisfies as it looks bit erroneous.
the program is as follows:-
void permute(char s[], int d)
{
int i;
if(d == strlen(s))
printf("%s",s);
else
{
for(i=d;i<strlen(s);i++)
{
swap(s[d],s[i]);
permute(s,d+1);
swap(s[d],s[i]);
}
}
}
If this program looks good (it is giving error when i ran it), then please provide a small example to understand this, as i am still developing recursion concepts..
Any other efficient algorithm, if exists, can also be discussed....
And Please,, this is not a HW........
Thanks.............
The code looks correct, though you only have the core of the algorithm, not a complete program. You'll have to provide the missing bits: headers, a main function, and a swap macro (you could make swap a function by calling it as swap(s, d, i)).
To understand the algorithm, it would be instructive to add some tracing output, say printf("permute(%s, %d)", s, d) at the beginning of the permute function, and run the program with a 3- or 4-character string.
The basic principle is that each recursive call to permute successively places each remaining element at position d; the element that was at position d is saved by putting it where the aforementioned remaining element was (i.e. the elements are swapped). For each placement, permute is called recursively to generate all desired substrings after the position d. So the top-level call (d=0) to permute successively tries all elements in position 0, second-level calls (d=1) try all elements in position 1 except for the one that's already in position 0, etc. The next-to-deepest calls (d=n-1) have a single element to try in the last position, and the deepest calls (d=n) print the resulting permutation.
The core algorithm requires Θ(n·n!) running time, which is the best possible since that's the size of the output. However this implementation is less efficient that it could be because it recomputes strlen(s) at every iteration, for a Θ(n²·n!) running time; the simple fix of precomputing the length would yield Θ(n·n!). The implementation requires Θ(n) memory, which is the best possible since that's the size of the input.
For an explanation of the recursion see Gilles answer.
Your code has some problems. First it will be hard to implement the required swap as a function in C, since C lacks the concept of call by reference. You could try to do this with a macro, but then you'd either have to use the exclusive-or trick to swap values in place, or use a temporary variable.
Then your repeated use of strlen on every recursion level blows up your complexity of the program. As you give it this is done at every iteration of every recursion level. Since your string even changes (because of the swaps) the compiler wouldn't even be able to notice that this is always the same. So he wouldn't be able to optimize anything. Searching for the terminating '\0' in your string would dominate all other instructions by far if you implement it like that.

Resources