【问题标题】:int pointer into void pointer and then into double pointerint 指针变为 void 指针,然后变为 double 指针
【发布时间】:2014-01-24 10:09:50
【问题描述】:
#include <stdio.h>
#include <string.h>

main()
{
    int an_int;
void *void_pointer = &an_int;
double *double_ptr = void_pointer;
*double_ptr = 10;

printf("%d", sizeof(*double_ptr));

}

这个程序的输出是 8.
这是怎么发生的??
我的意思是 double_ptr 指向 4 字节内存,但输出仍然是 8 。
*其他 4 个字节从何而来???这个程序应该崩溃,因为其他 4 个字节没有分配给它。 *
请解释一下??

【问题讨论】:

  • 旁注:当打印类型为size_t 的值时,您应该使用%zu

标签: c void-pointers


【解决方案1】:

C 是静态类型的,表达式sizeof *double_ptr 仅根据这些静态类型规则计算,即double_ptr 指向大小为8double

此程序具有未定义的行为,因为您正在写入您不“拥有”的内存范围。所有的赌注都没有了,它可能会崩溃或不会。在进行这种讨厌的转换时,您应该对此负责,而不是编译器。

编辑,挑剔:

  • 符合标准的编译器不应允许没有返回类型的函数。提高警告级别。
  • 在此处发布代码时,请正确缩进
  • sizeof 运算符的结果不是int,而是size_t 一个无符号类型。用"%d" 打印也有未定义的行为。使用"%zu"

【讨论】:

    【解决方案2】:

    我的意思是 double_ptr 指向 4 字节内存,但输出仍然是 8。

    这是因为sizeof 是根据类型或表达式的类型计算的。此外,在这种情况下,无论指针的值如何,都可以在编译时对其进行全面评估。

    *其他4个字节从哪里来???

    它们属于与int 位置相邻的内存区域。此区域未分配给您打算编写的对象,因此它是未定义的行为。很有可能您正在写入指针本身,如果编译器在 an_int 之后立即将 void_pointer 放入内存中,则可能会发生这种情况。

    这个程序应该崩溃,因为其他 4 个字节没有分配给它。

    不幸的是,并非所有未定义的行为都会导致崩溃。当无效程序不会崩溃时,这是 C 语言中的常见情况。例如,所有缓冲区溢出漏洞利用都依赖于程序在表现出未定义行为后不崩溃的能力。

    【讨论】:

      【解决方案3】:

      sizeof 是编译时运算符。因此它检查指针可能指向的数据类型(双 8 字节),因此输出为 8。

      int main()
      {
          int an_int;
      void *void_pointer = &an_int;
      double *double_ptr = void_pointer;
      *double_ptr = 10;
      
      printf("%d %d",*double_ptr,sizeof(*double_ptr));
      
      } 
      

      我已经编辑了一点。它在尝试使用指针访问内存时崩溃。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-30
        • 2021-07-22
        • 2013-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-31
        • 1970-01-01
        相关资源
        最近更新 更多