【问题标题】:Explanation of inrementing pointer to integer. Pointer arithmetic in C解释指向整数的 inrementing 指针。 C中的指针算法
【发布时间】:2020-10-03 23:43:39
【问题描述】:
int * ptr = (int *) 0x108; // 264 in bin
printf("%d\n", ptr);

我真的不明白发生了什么-当我像++ 这样的操作时,它的值会增加 4(可能是因为 sizeof(int) 是 4)但是有人可以在这里向我解释这是怎么回事吗?访问此类指针时出现错误。为什么?

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    是的,这是一个内存地址,但没有分配给你。如果你在 valgrind 上运行它:

    int * ptr = (int *) 0x108; // 264 in bin
    printf("%d\n", *ptr);
    

    你明白了

    ==755107== 地址 0x108 没有被堆栈、malloc 或(最近)释放

    您的进程无权访问内存地址。之所以打印264是因为这是0x108的十进制对话

    printf( "%d", 0x108);
    

    您向 printf 提供了 %dprintf 尝试将值转换为整数。传%p取回地址

    【讨论】:

      【解决方案2】:

      使用int * ptr = (int *) 0x108;,您的指针指向地址0x108。 如果要设置整数,请使用

      int *ptr = malloc(sizeof(int));
      *ptr = 0x108
      

      使用printf("%d\n", ptr);,您只需打印 ptr 的内容,假设它是一个数字。这就是您实际打印地址的原因。要打印内容,请使用

      printf("%d\n", *ptr);
      

      请注意,当您访问不太可能分配给当前进程的内存时,这(使用您的旧声明和 ptr 设置)应该会出现段错误。

      【讨论】:

      • 是的,但是当我打印指针的内容时,它每次都会崩溃,但据我所知,它只是一种硬编码内存地址的方式
      • 是的,它会崩溃,因为您不拥有 0x108 处的内存。要使其工作,您需要使用您拥有的地址,例如可以通过使用 malloc 来完成。
      【解决方案3】:

      基本上,是的,您可以将它用于诸如内存映射 I/O 之类的事情。

      例如,假设您在嵌入式系统中有一个内存映射随机发生器设备,它将拦截对位置0xf100 的内存访问,并在数据总线上放置一个随机值。您可以使用如下代码:

      int getRandom(void) {
          static int *randIo = (int*)0xf100;
          return *randIo;
      }
      

      重要的一点是间接*randIo。从内存位置获取一个(不是内存位置本身,如果没有间接,它将是randIo)。

      在你的情况下是*ptr,而不是ptr。但是在任意(受内存保护的)系统上会做什么将是任何人的猜测:-)

      【讨论】:

        【解决方案4】:

        当我进行像 ++ 这样的数学运算时,它会将值加 4 (可能是因为 sizeof(int) 是 4)但有人可以向我解释 这是怎么回事?

        ptr 是指向 int 的指针。当您将整数添加到指针时,您将执行指针算术。 ++ 运算符将指针前进到内存中的下一个 int。如果您机器上的 int 大小为 4 个字节,则地址将以 4 个字节递增。指针算术接近于数组操作。 arr[x] = arr + x。也就是说,如果你想获得数组的第五个元素,你可以使用索引(arr[4])或者你可以使用指针算法(比如 arr + 4)。

        请注意,当您访问不太可能分配给当前进程的内存时,这(使用您的旧声明和 ptr 设置)应该会出现段错误。

        由于未检查 C 中的数组索引(这是程序员的责任),您可以轻松访问未分配给您的进程的内存地址,这将导致操作系统错误。 对于地址 0x108,您可能总是会出错,因为在某些操作系统中,低地址没有分配给用户。通常是 64K。这样做是为了用指针捕获错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-08-14
          • 1970-01-01
          • 2021-12-31
          • 1970-01-01
          相关资源
          最近更新 更多