I want to use user defined stack for my program which has a large number of recursive calls ? Will it be useful to define user defined stack?
-
Depends on the user defined stack, we need to see it. – Arnav Borborah Aug 28 '16 at 18:55
-
Did you mean heap by built in stack ? – Shravan40 Aug 28 '16 at 18:58
-
.. or just create a bigger stack if you're on posix. – lorro Aug 28 '16 at 19:00
2 Answers
There are a few ways to do this.
Primarily, two:
(1) Use the CPU/processor stack. There are some variants, each with its own limitations.
(2) Or, recode your function(s) to use a "stack frame" struct that simulates a "stack". The actual function ceases to be recursive. This can be virtually limitless up to whatever the heap will permit
For (1) ...
(A) If your system permits, you can issue a syscall
to extend the process's stack size. There may be limits on how much you can do this and collisions with shared library addresses.
(B) You can malloc
a large area. With some [somewhat] intricate inline asm trickery, you can swap this area for the stack [and back again] and call your function with this malloc
area as the stack. Doable, but not for the faint of heart ...
(C) An easier way is to malloc
a large area. Pass this area to pthread_attr_setstack
. Then, run your recursive function as a thread using pthread_create
. Note, you don't really care about multiple threads, it's just an easy way to avoid the "messy" asm trickery.
With (A), assuming the stack extend syscall permits, the limit could be all of available memory permitted for stack [up to some system-wide or RLIMIT_* parameter].
With (B) and (C), you have to "guess" and make the malloc
large enough before you start. After it has been done, the size is fixed and can not be extended further.
Actually, that's not quite true. Using the asm trickery repeatedly [when needed], you could simulate a near infinite stack. But, IMO, the overhead of keeping track of these large malloc areas is high enough that I'd opt for (2) below.
For (2) ...
This can literally expand/contract as needed. One of the advantages is that you don't need to guess beforehand at how much memory you'll need. The [pseudo] stack can just keep growing as needed [until malloc
returns NULL
:-)].
Here is a sample recursive function [treat loosely as pseudo code]:
int
myfunc(int a,int b,int c,int d)
{
int ret;
// do some stuff ...
if (must_recurse)
ret = myfunc(a + 5,b + 7,c - 6,d + 8);
else
ret = 0;
return ret;
}
Here is that function changed to use a struct
as a stack frame [again, loose pseudo code]:
typedef struct stack_frame frame_t;
struct stack_frame {
frame_t *prev;
int a;
int b;
int c;
int d;
};
stack_t *free_pool;
#define GROWCOUNT 1000
frame_t *
frame_push(frame_t *prev)
{
frame_t *cur;
// NOTE: we can maintain a free pool ...
while (1) {
cur = free_pool;
if (cur != NULL) {
free_pool = cur->prev;
break;
}
// refill free pool from heap ...
free_pool = calloc(GROWCOUNT,sizeof(stack_t));
if (free_pool == NULL) {
printf("frame_push: no memory\n");
exit(1);
}
cur = free_pool;
for (int count = GROWCOUNT; count > 0; --count, ++cur)
cur->prev = cur + 1;
cur->prev = NULL;
}
if (prev != NULL) {
*cur = *prev;
cur->prev = prev;
cur->a += 5;
cur->b += 7;
cur->c += 6;
cur->d += 8;
}
else
memset(cur,0,sizeof(frame_t));
return cur;
}
frame_t *
frame_pop(frame_t *cur)
{
frame_t *prev;
prev = cur->prev;
cur->prev = free_pool;
free_pool = cur;
return prev;
}
int
myfunc(void)
{
int ret;
stack_t *cur;
cur = frame_push(NULL);
// set initial conditions in cur...
while (1) {
// do stuff ...
if (must_recurse) {
cur = frame_push(cur);
must_recurse = 0;
continue;
}
// pop stack
cur = frame_pop(cur);
if (cur == NULL)
break;
}
return ret;
}

- 30,627
- 4
- 24
- 48
All of functions, objects, variable and user defined structures use memory spaces which is control by OS and compiler. So, it means your defined stack works under a general memory space which is specified for the stack of your process in OS. As a result, it does not have a big difference, but you can define an optimized structure with high efficiency to use this general stack much more better.

- 906
- 4
- 19