我写了这样的代码
int a = 0;
int b = 0;
int *m = (int *)malloc(2* sizeof(int));
printf("%x, %x\n", &a, &b);
printf("%x, %x", &m[0], &m[1]);
Run Code Online (Sandbox Code Playgroud)
得到结果:
46372e18, 46372e1c
d062ec20, d062ec24
Run Code Online (Sandbox Code Playgroud)
这不是堆栈增长和堆积?
要了解" 1 "堆栈2的增长方式,必须至少进行一次函数调用.像这样的东西,例如:
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
static ptrdiff_t
stack_probe(uintptr_t stack_addr_from_main)
{
int var;
uintptr_t stack_addr_from_me = (uintptr_t)&var;
return ((intptr_t) stack_addr_from_me) -
((intptr_t) stack_addr_from_main);
}
int
main(void)
{
int var;
uintptr_t stack_addr_from_main = (uintptr_t)&var;
ptrdiff_t stack_delta = stack_probe(stack_addr_from_main);
printf("Stack offset from one function call = %td\n", stack_delta);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
你必须做,这样一来,因为大多数编译器分配所有的堆栈空间的函数调用一次全部,入境时,在什么叫做"栈帧",并在他们认为合适的组织空间.因此,比较同一函数的两个局部变量的地址并不能告诉你任何有用的东西.您还必须注意编译此程序并关闭"内联"; 如果编译器允许合并stack_probe到main,那么它都将再次成为一个堆栈帧,其结果将是没有意义的.(有些编译器允许你逐个函数地控制内联,但据我所知,没有标准的方法可以做到这一点.)
该程序打印的数字由C标准3 "未指定" (表示"它将打印一些数字,但标准不要求它是任何特定的数字").但是,几乎所有计算机上你都可能会在今天开始使用它,它会打印一个负数,这意味着堆栈会向下增长.如果您设法在运行HP-UX的PA-RISC计算机上运行它(它可能甚至不能编译,不幸的是;我不记得HP-UX是否曾经拥有符合C99标准的库)它将打印一个正数,并且这意味着堆栈向上增长.
有一些计算机,这个程序打印的数字不会有任何意义,因为它们相当于"堆栈"不一定是连续的内存块.查找最简单版本的"拆分堆栈".
顺便说一句,"堆"不一定会成长或下降.连续调用malloc返回指针,彼此之间没有任何有意义的关系,总是如此.
1可以有多个堆栈,例如在使用线程时.
2有趣的事实:"堆栈"这个词在C标准中没有出现.需要支持递归函数调用,但实现如何管理完全取决于实现.
3此外,该程序是否将编译是实现定义的,因为不需要提供intptr_t和实现uintptr_t.但是,如果我没有使用这些类型,程序将有未定义的行为("它允许做任何事情,包括崩溃并删除所有代码"),因为你只允许采取两个指针的差异当他们指向同一个数组时,这些不是.
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |