【问题标题】:where the size of pointer variable gets stored?指针变量的大小存储在哪里?
【发布时间】:2011-08-26 15:37:01
【问题描述】:
 #include <stdio.h>

 int main(void)
 {
int a[5]={1,2,3,4,5};
int *ptr=(int*)(&a+1);
printf("%d %d\n",*(a+1),*(ptr-1));
return 0;
}

输出:

2 5

这里的语句*ptr= (int*)(&amp;a+1) 1 没有添加到&amp;a。实际上它就像&amp;a + sizeof(a)。现在我的问题是指针变量的大小存储在哪里,或者如果它没有存储,那么它是如何计算的。在int, float, char 等情况下,它们的大小是在编译器中预定义的,因此 int *a 是不同的情况。真的只有地址存储在指针变量中吗?关于指针变量的元数据存储在哪里?

【问题讨论】:

标签: c arrays pointers


【解决方案1】:

由于您的变量声明 int a[5] = ...,编译器知道 a 的类型为 int [5](因此,sizeof(a) 将返回 20)。由于编译器知道a 的类型,因此获取a 的地址将产生一个正确类型的指针。这可能有点令人惊讶:&amp;a 不会产生 int**,而是产生 int (*)[5](指向五个整数数组的指针)。

所以在执行的时候

int *ptr=(int*)(&a+1);

您获取a 的地址,加一个(由于 C/C++ 指针算法的工作方式,指针引用的地址增加了sizeof(a) 字节),然后将结果转换为 int。所以此时,ptr 指向数组最后一个元素的后面(偏移量 20)。

然后您将指针转换为int* 并使用*(ptr-1),因此您在偏移量 16 处取消引用 int 值 - 这恰好是最后一个数组元素所在的位置。

【讨论】:

    【解决方案2】:

    它不会被存储。编译器在编译代码时当然需要跟踪这一点,但在此之后,它基本上只是硬编码到生成的指令中。

    【讨论】:

      【解决方案3】:

      &a 是 int (*)[5] 类型,即 &a 是指向 array 的指针,而不是指向 int 的指针。编译器(显然)知道数组大小是多少,并将其用于指针运算。

      【讨论】:

        【解决方案4】:

        指针具有“双重类型”。一方面,它是一个具有自己大小的指针(假设某些系统上的每个指针有 4 个字节)。另一方面,它是指向具有大小的对象的指针(void * 除外)。

        在 C 中通常不能直接访问类型。你不能问“变量的类型是什么”。

        但始终可以通过sizeof 访问大小。所以int *本身可能使用4个字节,但是编译器知道它指向一个整数,它知道整数的大小。 对于struct xyz *,指针本身可能又是4 个字节,但编译器知道它指向一个结构,并且知道结构的大小。重要的是指针的类型超出“指针”。

        所以,如果你定义了struct xyz *ptr,你总是可以通过检查sizeof(*ptr)来找出指针所指向的大小。即使ptr 未初始化,您也可以这样做。

        ptr 定义为void * 时,您唯一不能做的就是检查sizeof(*ptr)

        就“元数据”而言,都是指针的类型。

        【讨论】:

          【解决方案5】:

          指针只是一个内存地址,没有元数据。将 N 添加到 T* 类型的指针会导致将 N*sizeof(T) 添加到地址值。编译器在编译过程中知道每种类型的大小,没有存储任何内容。

          • a+1指向a中的第二个int,因为它将a视为int*即指向第一个元素的指针,即sizeof(int)被添加到内存地址
          • &amp;a+1指向“第二个int[5]数组”,即在内存地址上加上sizeof(int[5])
          • ptr-1 指向“第二个数组”的第一个元素(即 a 的最后一个元素)之前的 int

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-03-26
            • 2010-10-02
            • 1970-01-01
            • 2018-02-01
            • 2010-09-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多