在 Linux Debian 上从指针计算 C 中的堆栈内存大小?
Calculating stack memory size in C from pointers, on Linux Debian?
受到 this related SO answer 的启发,我试图在 Linux Debian 9 上获取堆栈内存使用情况(与堆内存不同),但没有取得太大成功。我创建了一些未产生预期结果的测试代码:
size_t top_of_stack = 0;
int main(void) {
int x = 0;
top_of_stack = (size_t) &x;
printf("Top of stack in main(): %lu\n", top_of_stack);
int y = 0;
size_t ss1 = (size_t) &y;
printf("Top of stack in main() ss1: %lu\n", ss1);
printf("Diff in main() top - ss1: %lu\n", top_of_stack - ss1);
long z = 0;
size_t ss2 = (size_t) &z;
printf("Top of stack in main() ss2: %lu\n", ss2);
printf("Diff in main() ss1 - ss2: %lu\n", ss1 - ss2);
double dd1[100];
dd1[99] = 12.0;
dd1[98] = 121.0;
dd1[97] = 122.0;
size_t ss3 = (size_t) &(dd1[99]);
printf("Top of stack in main() ss3: %lu\n", ss3);
printf("Diff in main() ss2 - ss3: %lu\n", ss2 - ss3);
return 0;
}
打印输出:
Top of stack in main(): 140733255163788
Top of stack in main() ss1: 140733255163784
Diff in main() top - ss1: 4
Top of stack in main() ss2: 140733255163776
Diff in main() ss1 - ss2: 8
Top of stack in main() ss3: 140733255163768
Diff in main() ss2 - ss3: 8
在三个“Diff”打印输出中,只有第一个似乎是正确的。第二个没有说明创建了两个 long
变量(long z
和 size_t ss1
),而不是一个。第三个“差异”报告没有说明已创建 100 doubles
的数组,最后三个项目已分配值的事实。
如何让它发挥作用?
请注意,虽然我可以在我的系统中包含“alloc.h”header,但 stackavail()
功能不可用。这就是我尝试开发自己的解决方案的原因。
C 不对堆栈布局做出任何保证。就编译器而言,它可以按照自己喜欢的方式添加或删除变量,只要不影响可观察的行为即可。它还可以以任何它想要的方式引入填充。
我不知道有什么方法可以准确地做到这一点。但是,如果您只需要一个不需要在运行时计算的快速估计,只需对所有局部变量求和即可。它不会准确,并且可能由于填充和其他因素而略低于实际值。
但是比较指针是个坏主意。如果你有两个指针,void *p, *q;
那么操作 p-q
是没有意义的,除非 p
和 q
指向同一个对象。该操作实际上可能会调用未定义的行为。 This answer 解释一下。
受到 this related SO answer 的启发,我试图在 Linux Debian 9 上获取堆栈内存使用情况(与堆内存不同),但没有取得太大成功。我创建了一些未产生预期结果的测试代码:
size_t top_of_stack = 0;
int main(void) {
int x = 0;
top_of_stack = (size_t) &x;
printf("Top of stack in main(): %lu\n", top_of_stack);
int y = 0;
size_t ss1 = (size_t) &y;
printf("Top of stack in main() ss1: %lu\n", ss1);
printf("Diff in main() top - ss1: %lu\n", top_of_stack - ss1);
long z = 0;
size_t ss2 = (size_t) &z;
printf("Top of stack in main() ss2: %lu\n", ss2);
printf("Diff in main() ss1 - ss2: %lu\n", ss1 - ss2);
double dd1[100];
dd1[99] = 12.0;
dd1[98] = 121.0;
dd1[97] = 122.0;
size_t ss3 = (size_t) &(dd1[99]);
printf("Top of stack in main() ss3: %lu\n", ss3);
printf("Diff in main() ss2 - ss3: %lu\n", ss2 - ss3);
return 0;
}
打印输出:
Top of stack in main(): 140733255163788
Top of stack in main() ss1: 140733255163784
Diff in main() top - ss1: 4
Top of stack in main() ss2: 140733255163776
Diff in main() ss1 - ss2: 8
Top of stack in main() ss3: 140733255163768
Diff in main() ss2 - ss3: 8
在三个“Diff”打印输出中,只有第一个似乎是正确的。第二个没有说明创建了两个 long
变量(long z
和 size_t ss1
),而不是一个。第三个“差异”报告没有说明已创建 100 doubles
的数组,最后三个项目已分配值的事实。
如何让它发挥作用?
请注意,虽然我可以在我的系统中包含“alloc.h”header,但 stackavail()
功能不可用。这就是我尝试开发自己的解决方案的原因。
C 不对堆栈布局做出任何保证。就编译器而言,它可以按照自己喜欢的方式添加或删除变量,只要不影响可观察的行为即可。它还可以以任何它想要的方式引入填充。
我不知道有什么方法可以准确地做到这一点。但是,如果您只需要一个不需要在运行时计算的快速估计,只需对所有局部变量求和即可。它不会准确,并且可能由于填充和其他因素而略低于实际值。
但是比较指针是个坏主意。如果你有两个指针,void *p, *q;
那么操作 p-q
是没有意义的,除非 p
和 q
指向同一个对象。该操作实际上可能会调用未定义的行为。 This answer 解释一下。