gpt4 book ai didi

c - 为什么堆栈和堆都会增长?

转载 作者:太空宇宙 更新时间:2023-11-04 00:16:07 24 4
gpt4 key购买 nike

我写这样的代码

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]);

并得到结果:

46372e18, 46372e1c
d062ec20, d062ec24

那堆不就是往下堆吗?

最佳答案

要了解“the”1 “stack”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;
}

你必须这样做,因为大多数编译器为函数调用分配所有堆栈空间一次,在入口时,在所谓的“堆栈框架”中,并在其中组织空间他们认为合适。因此,比较同一函数的两个局部变量的地址并不能告诉您任何有用的信息。您还必须注意在关闭“内联”的情况下编译该程序;如果允许编译器将stack_probe合并到main中,那么它又将是一个堆栈帧,结果将毫无意义。 (一些编译器允许您在逐个函数的基础上控制内联,但据我所知,没有标准的方法来做到这一点。)

C 标准3“未指定”此程序打印的数字(这意味着“它将打印一些 数字,但标准不要求它是任何特定的数字”)。然而,在今天你可能接触到的几乎所有计算机上,它都会打印一个负数,这意味着堆栈向下增长。如果您设法在运行 HP-UX 的 PA-RISC 机器上运行它(不幸的是,它甚至可能无法编译;我不记得 HP-UX 是否曾经有过符合 C99 的库),它将打印一个正数,并且这意味着堆栈向上增长。

曾经有计算机,在这些计算机上,此程序打印的数字没有任何意义,因为它们的“堆栈”等价物不一定是连续的内存块。查找“拆分堆栈”以获得最简单的版本。

顺便说一句,“堆”不一定会向上向下增长。对 malloc 的连续调用始终会返回相互之间没有任何意义关系的指针。


1 可以有多个堆栈,例如在使用线程时。

2 有趣的事实:“堆栈”一词在 C 标准中没有出现。需要支持递归函数调用,但实现如何管理这完全取决于实现。

3 此外,该程序是否编译由实现定义,因为实现不需要提供intptr_tuintptr_t。但是如果我没有使用这些类型,程序就会有未定义行为(“它可以做任何事情,包括崩溃和删除所有代码”)因为你只被允许当两个指针指向同一个数组时取两个指针的差值,而这些不是。

关于c - 为什么堆栈和堆都会增长?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46037992/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com