c - 为什么 C 中的 64 位指针只使用 4 个字节而不是预期的 8 个字节?

标签 c linux pointers 64-bit

我正在努力成为“一个真正的男人”,也就是从 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*)。

但是为什么我没有丢失任何数据呢?纯粹是巧合/运气?

最佳答案

指针对象(cd)占用的存储空间与数据(这些指针指向的对象)占用的存储空间无关。

这是一个假设的内存映射,显示了如何布置这些值(cd的地址凭空组成,假设大端布局):

  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 是适用于相当狭窄的应用程序领域(系统编程、非图形服务器端处理等)的正确工具,但对于一般应用程序编程,它已经被更易于使用的语言所掩盖。

此外,Real Programmers use Fortran .

关于c - 为什么 C 中的 64 位指针只使用 4 个字节而不是预期的 8 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32276192/

相关文章:

c - 等待超时信号,如果收到信号则继续执行(没有与信号关联的操作)

c - 我如何一次发送一个字符这个字符串?

php - Nginx 无法与 uwsgi 对话(连接过早关闭)

pointers - 如何递归传递可变引用?

c - 二维数组的三重指针的目的是什么?

c++ - 与动态库链接导致的可执行运行时崩溃

c - c "Hello world"中的字符串?

python - 我如何通过守护线程收听标准输入

linux - 找不到 VSTS 构建问题文件 'git' - Linux 专用代理

c++ - 虚拟保护大小