我正在努力成为“一个真正的男人”,也就是从 C++ 转向 C。指针和 malloc 有时会让人感到困惑。我使用的是没有任何标志的 gcc,64 位 Linux。
所以我的第一个问题是:
int* c;
int* d;
void* shared = malloc(sizeof(int)*2);
c = shared;
d = shared + sizeof(int);
*c = 123;
*d = 321;
printf("c: %p, *c: %i\n", (void*)c, *c);
printf("d: %p, *d: %i\n", (void*)d, *d);
printf("sizeof(c): %lu, sizeof(d): %lu\n", sizeof(c), sizeof(d));
输出: c:0x1c97050,*c:123 d:0x1c97054,*d:321 sizeof(c): 8, sizeof(d): 8
将两个内存地址转换为十进制并检查它们的差异,得到 4。 这意味着它们在内存中彼此相距 4 个字节? 这意味着 int 用 4 个字节表示,sizeof(int) = 4。
但是由于 64 位内存,一个指针(我猜是任何类型的,但在我们的例子中指向 int)是用 8 个字节表示的? 这意味着我犯了一个错误,只分配了 4 个字节而不是所需的 8 个字节(int 而不是 int*)。
但是为什么我没有丢失任何数据呢?纯粹是巧合/运气?
最佳答案
指针对象(c
和 d
)占用的存储空间与数据(这些指针指向的对象)占用的存储空间无关。
这是一个假设的内存映射,显示了如何布置这些值(c
和d
的地址凭空组成,假设大端布局):
Item Address 0x01 0x02 0x03 0x04
---- ------- ---- ---- ---- ----
shared 0x0000000001c97050 00 00 00 7b
0x0000000001c97054 00 00 01 41
...
c 0x000000fffff86400 00 00 00 00
0x000000fffff86404 01 c9 70 50
d 0x000000fffff86408 00 00 00 00
0x000000fffff8640c 01 c9 70 54
在 malloc
调用中,您分配了空间来存储 2 个 int
对象,每个对象占用 4 个字节。 shared
的第一个元素位于地址 0x0000000001c97050
,存储 4 字节值 123
,位于地址 0x0000000001c97054
的第二个元素存储 4 字节值 321
。
指针c
位于地址0x000000fffff86400
,存储shared<的第一个元素的8字节地址
,即0x0000000001c97050
。同样,位于地址0x000000fffff86408
处的指针d
存储shared第二个元素的地址,即0x0000000001c97054
。
TL;DR - 您为数据分配了正确的内存量,这才是最重要的。
无端咆哮
I'm trying to become "a real man", aka moving from C++ to C
学习 C 并不会让你变得有男子气概;它使你成为了解 C 的人。围绕 C 语言、C 编程和 C 程序员存在着许多糟糕的神话。是的,它的低级抽象迫使你时刻保持警惕,但这并不会让你变得有男子气概,而只会让你变得偏执。 C 是适用于相当狭窄的应用程序领域(系统编程、非图形服务器端处理等)的正确工具,但对于一般应用程序编程,它已经被更易于使用的语言所掩盖。
关于c - 为什么 C 中的 64 位指针只使用 4 个字节而不是预期的 8 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32276192/