我想为我的程序使用用户定义的堆栈,它有大量的递归调用?定义用户定义的堆栈会有用吗?使用内存时用户定义堆栈和内置堆栈之间的区别是什么?
回答
所有的函数,对象,变量和用户定义的结构都使用由操作系统和编译器控制的内存空间。所以,这意味着您定义的堆栈在为您的OS中的进程堆栈指定的通用内存空间下工作。因此,它没有太大的区别,但是你可以定义一个高效率的优化结构来更好地使用这个通用堆栈。
有几种方法可以做到这一点。
首先,:
(1)使用CPU /处理器堆栈。有一些变体,每个都有其自身的限制。 (2)或者,重新编码您的函数以使用模拟“堆栈”的“堆栈帧”结构。实际的函数不再是递归的。这可能是几乎是无限高达无论堆将允许
对于(1)...
(A)如果您的系统允许,您可以发出syscall
延长进程的堆栈大小。可以有多少限制可以做到这一点,并与共享库地址冲突。 (B)malloc
大面积。有了一些[有点]错综复杂的内联asm欺骗,你可以将这个区域换成堆栈[并且再回来],并用这个malloc
区域作为堆栈调用你的函数。可以,但不适合心灵的隐隐...
(C)更简单的方法是到malloc
大面积。通过这个区域到pthread_attr_setstack
。然后,使用pthread_create
作为线程运行递归函数。请注意,你并不关心多线程,它只是避免“混乱”asm欺骗的一种简单方法。 (A),假设堆栈扩展了系统调用许可,限制可以是堆栈允许的所有可用存储器[高达某些系统范围或RLIMIT_ *参数]。 (B)和(C),在开始之前,您必须“猜测”并使malloc
足够大。完成后,尺寸是固定的,可以进一步扩展而不是。
其实这并不完全正确。反复使用asm技巧[需要时],可以模拟接近无限的堆栈。但是,国际海事组织,跟踪这些大malloc区域的开销足够高,我会选择(2)下面。
对于(2)...
这可以从字面上扩大/按需要合同。其中一个优点是,您无需事先猜测您需要多少内存。 [pseudo]堆栈可以根据需要保持增长[直到malloc
返回NULL
:-)]。
下面是一个示例递归函数[松散当作伪代码]:
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;
}
下面是函数更改为使用struct
用作堆栈帧[再次,松散伪代码]:
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;
}
- 1. 堆栈和堆之间有什么区别?
- 2. 描述堆栈和列表堆栈之间的区别?
- 3. 内存分配,堆栈和堆栈
- 4. 栈和堆内存
- 5. 数组和堆栈之间的区别?
- 6. 关于堆栈和堆栈内存使用的问题
- 7. 堆栈和堆栈帧有什么区别?
- 8. 进程堆栈和CPU堆栈有什么区别?
- 9. 线程堆栈和进程堆栈有什么区别
- 10. 递归函数与使用内存使用堆栈之间的区别
- 11. 进程虚拟内存 - 堆栈和堆之间的空间
- 12. 其他内存区域(堆栈和堆栈除外)?
- 13. 在JVM中,堆栈内存将占用什么内存空间?
- 14. 堆栈内存位置
- 15. Wicket,页面堆栈和内存使用
- 16. C程序的堆栈和堆内存
- 17. 堆栈和堆内存的影响?
- 18. 堆栈跟踪和回溯之间有什么区别?
- 19. 任务和活动堆栈:两者之间有什么区别。
- 20. Java堆和堆栈内存分配
- 21. g ++在堆栈上分配未使用的内存是什么?
- 22. .NET EXE和DLL之间的堆栈/堆区别
- 23. 什么是更高效的堆栈内存或堆?
- 24. 内核堆栈与用户模式应用程序堆栈
- 25. 全堆栈,堆栈交换等,什么是堆栈?
- 26. 堆栈和堆栈内存存储在C++
- 27. ptrace会中断CPU上下文,用户空间堆栈还是内核堆栈?
- 28. 堆中的对象与堆栈内存之间的混淆
- 29. 内存中的堆栈实际上是一个堆栈吗?
- 30. 为什么堆栈和堆都需要内存分配
取决于用户定义的堆栈,我们需要看到它。 –
你的意思是堆内置堆? – Shravan40
..或者只是在posix上创建一个更大的堆栈。 – lorro