【问题标题】:C: Accessing (int) via (void *) pointing to (void *) pointing to (int) by typecasting and dereferencingC: 通过 (void *) 指向 (void *) 指向 (int) 通过类型转换和取消引用访问 (int)
【发布时间】:2016-09-18 08:19:00
【问题描述】:

我正在摆弄 C 中的指针,但仍然不确定一些非常基础的东西。我想出了以下示例代码:

#include <stdio.h>

int main(void)
{
    int num = 42;              // we want to access this integer
    void *vptrB = &num;        // pointer B points to the integer
    void *vptrA = &vptrB;      // pointer A points to pointer B
    printf("%d\n", * (int *) * (void **) vptrA);
    return 0;
}

内存应该是这样的:

是否有其他方法可以访问整数?这个例子有什么不好/不安全的吗? * (int *) * (void **) vptrA 是通过vptrAvptrB 访问num 的唯一方法吗?

【问题讨论】:

  • 您为什么将指针保留为void * 而不是使用正确的类型?您应该尝试使用类型系统,而不是与之抗争。
  • 哎哟;提醒我以后不需要阅读您的代码,好吗?理解起来很痛苦。如果你可以引用vptrB,那么你可以让它更简单,但如果你只能访问vptrA,那么你写的看起来是正确的——但我没有通过编译器运行它来仔细检查我'已经像编译器一样解释它。
  • @TomKarzes:我确信这只是理解复杂指针而不是其他任何东西的练习。我当然希望它不代表生产代码将如何编写。
  • @Zastai,不幸的是,尽管您的方法可能适用于许多系统,但不能保证适用于每个系统,因为指向不同类型的指针不一定是相同的大小或具有相同的表示。为了安全起见,您需要执行 OP 提供的转换和引用字符串。
  • 到底是什么问题? “有没有其他方法可以访问整数?”,是的,显然你可以写num,或int *p = &amp;num; ...*p 或一千个其他的东西。主要不涉及首先创建vptrAvptrB

标签: c void-pointers


【解决方案1】:

是否有其他方法可以访问整数?

 int num = 42;
 int *vptrB = &num;
 int **vptrA = &vptrB;
 // All print 42
 printf("%d\n", num);
 printf("%d\n", *vptrB);
 printf("%d\n", **vptrA);

这个例子有什么不好/不安全的地方吗?

使用void* 来表示数据丢失类型、对齐方式、constvolatile 信息的地址。 void* 强制使用强制转换来随后解释引用的数据 - 这很容易出错。虽然代码在其转换中是正确的,但它容易受到维护错误和代码审查误解的影响。

【讨论】:

  • 使用 void * 而不使用强制转换确实会保留 constvolatile 信息。当然你可以把这些东西扔掉,但int *也是如此
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2014-02-06
  • 2014-10-22
相关资源
最近更新 更多