【发布时间】:2020-05-24 11:13:29
【问题描述】:
我在我的计算机(运行 Linux 的 64 位 Intel)上运行了以下程序。
#include <stdio.h>
void test(int argc, char **argv) {
printf("[test] Argc Pointer: %p\n", &argc);
printf("[test] Argv Pointer: %p\n", &argv);
}
int main(int argc, char **argv) {
printf("Argc Pointer: %p\n", &argc);
printf("Argv Pointer: %p\n", &argv);
printf("Size of &argc: %lu\n", sizeof (&argc));
printf("Size of &argv: %lu\n", sizeof (&argv));
test(argc, argv);
return 0;
}
程序的输出是
$ gcc size.c -o size
$ ./size
Argc Pointer: 0x7fffd7000e4c
Argv Pointer: 0x7fffd7000e40
Size of &argc: 8
Size of &argv: 8
[test] Argc Pointer: 0x7fffd7000e2c
[test] Argv Pointer: 0x7fffd7000e20
指针&argv的大小为8字节。我希望argc 的地址是address of (argv) + sizeof (argv) = 0x7ffed1a4c9f0 + 0x8 = 0x7ffed1a4c9f8,但它们之间有一个 4 字节的填充。为什么会这样?
我的猜测是这可能是由于内存对齐,但我不确定。
我注意到我调用的函数也有同样的行为。
【问题讨论】:
-
为什么不呢?它们可能相隔 174 个字节。答案将取决于您的操作系统和/或为
main设置的包装库。 -
@aschepler:它不应该依赖于为
main设置的任何包装器。在 C 语言中,main可以作为常规函数调用,因此它需要像常规函数一样接收参数,并且必须遵守 ABI。 -
@aschelper:我注意到其他函数也有相同的行为。
-
这是一个有趣的“思想实验”,但实际上,没有什么比“我想知道为什么”更重要的了。这些地址可以根据操作系统、编译器、编译器版本、处理器架构而改变,在“现实生活”中绝不应该依赖。
-
sizeof must be printed using
%zu的结果
标签: c memory-alignment