【发布时间】:2011-06-26 10:29:14
【问题描述】:
使用 C 程序增加或减少堆栈?
【问题讨论】:
-
那是什么意思?请说一些更详细的信息。你的堆栈是如何实现的?
-
这个问题没有研究。
-
你还没有告诉我们你尝试过什么或者你已经知道什么。
使用 C 程序增加或减少堆栈?
【问题讨论】:
是的,在 C 中,函数范围内的变量通常是通过堆栈来实现的。但是这个模型不是由 C 标准强加的,编译器可以以任何它喜欢的方式实现这一点。标准中甚至没有提到“堆栈”这个词,如果它在或减少的话,甚至更少。您永远不应该尝试对此进行假设。
【讨论】:
错误的二分法。除了增减之外,还有很多选择,其中一个就是每次函数调用都执行malloc的等价,为被调用者的自动存储获取内存,调用被调用者,返回后执行free的等价.更复杂的版本将一次分配大量的“堆栈”,并且仅在即将耗尽时分配更多。
我会在具有虚拟内存的现代机器上调用这两种非常糟糕的设计,但在没有 MMU 的微处理器上实现多进程操作系统时它们可能是有意义的,因为在每个进程中为堆栈保留一定范围的内存会浪费大量的地址空间。
【讨论】:
怎么样:
int stack_direction(void *pointer_to_local)
{
int other_local;
return (&other_local > pointer_to_local) ? 1 : -1;
}
...
int local;
printf("direction: %i", stack_direction(&local);
因此,您将调用堆栈上某个位置的变量地址与外部位置的变量地址进行比较。
【讨论】:
如果您只想知道堆栈是否已更改,您可以将最后插入的对象保留在堆栈中,查看它的顶部并比较两者。
【讨论】:
编辑
阅读 cmets。使用我的方法似乎无法确定堆栈方向。
结束编辑
在栈上声明一个数组变量,比较连续元素的地址。
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char buf[16];
printf("&buf[0]: %x\n&buf[1]: %x\n", &buf[0], &buf[1]);
return 0;
}
输出是:
misha@misha-K42Jr:~/Desktop/stackoverflow$ ./a.out
&buf[0]: d1149980
&buf[1]: d1149981
正如预期的那样,堆栈正在向下增长。
【讨论】:
您还可以使用内联汇编监控 ESP 寄存器。 ESP 寄存器保存未分配堆栈的地址。因此,如果将某些东西推入堆栈 - ESP 会减少,如果弹出 - ESP 会增加。 (还有其他修改堆栈的命令,例如函数调用/返回)。
例如,当我们尝试计算诸如斐波那契数(Visual Studio)之类的递归函数时,堆栈发生了什么:
#include <stdio.h>
int FibonacciNumber(int n) {
int stackpointer = 0;
__asm {
mov stackpointer, esp
}
printf("stack pointer: %i\n", stackpointer);
if (n < 2)
return n;
else
return FibonacciNumber(n-1) + FibonacciNumber(n-2);
}
int main () {
FibonacciNumber(10);
return 0;
}
【讨论】: