c++ - 取消引用指向未知类型变量的指针

标签 c++ c memory

我不知道如何解释我现在遇到的问题,如果我对问题的标题含糊不清,我深表歉意。

我现在拥有的是存储在变量中的虚拟地址列表。例如,我有

0x8c334dd

存储在一个 char 变量中。这个地址是另一个有数据的变量的地址。我想做的是转到该地址并获取存储在其中的数据。

我的假设是解除对指针的引用是最好的方法,不幸的是我不知道地址指向的变量的类型,那么在这种情况下解除引用是如何工作的呢?我不能这样做:*(char *) 8c334dd 因为我不知道地址指向的变量的类型...

如果我将其转换为 (int *),我会得到某些地址指向的某些变量的一些数据(记住我有多个地址),但对于其他地址,我是只是得到一个地址,我需要数据(这个变量是结构、字符等)。

我正在使用 ELF 符号表

最佳答案

通常,C++ 或 C 无法知道您拥有的指针类型。

通常解决这个问题的方法是让指针指向一个结构体,并在结构体中有一个已知的位置来指示数据的类型。通常已知位置是结构中的第一个位置。

例子:

// signature value; use any value unlikely to happen by chance
#define VAR_SIG 0x11223344

typedef enum
{
    vartypeInvalid = 0,
    vartypeInt,
    vartypeFloat,
    vartypeDouble,
    vartypeString,
    vartypeMax  // not a valid vartype
} VARTYPE;

typedef struct
{
    VARTYPE type;
#ifdef DEBUG
    uint32_t sig;
#endif // DEBUG
    union data
    {
        int i;
        float f;
        double d;
        char *s;
    };
} VAR;

然后您可以进行健全性检查:您可以查看 type 字段的值是否大于 vartypeInvalid 且小于 vartypeMax(并且您永远不需要在健全性检查代码中编辑这些名称;如果您添加更多类型,则将它们添加到列表中的 vartypeMax 之前)。此外,对于 DEBUG 构建,您可以检查签名字段 sig 是否包含一些特定的签名值。 (这意味着您初始化 VAR 实例的初始化代码当然需要始终设置 sig 字段。)

如果你做这样的事情,那么你如何初始化它?运行时代码将始终有效:

VAR v;

#ifdef DEBUG
v.sig = VAR_SIG;
#endif // DEBUG
v.type = vartypeFloat;
v.data = 3.14f;

如果想在编译时初始化怎么办?如果你想用整数值初始化它很容易,因为 int 类型是 union 中的第一个类型:

VAR v =
{
    vartypeInt,
#ifdef DEBUG
    VAR_SIG,
#endif // DEBUG
    1234
};

如果您使用的是 C 的 C99 兼容版本,您实际上可以使用字段名称初始化结构并让它分配任何类型。但是 Microsoft C 不兼容 C99,因此如果您想使用 floatdouble 值初始化您的结构,以上内容将是一场噩梦。 (如果将浮点值转换为整数,C 不仅会更改类型,还会对值进行四舍五入;而且据我所知,没有任何技巧可移植地获得正确表示 32 位的 32 位整数值在 C 程序的编译时 float 。)

Compile time float packing/punning

不过,如果您使用的是指针,那很容易。只需将 union 中的第一个字段名称设为指针类型,将指针转换为 void * 并如上所述初始化结构(指针将指向 1234 上面的位置) .

如果您正在阅读由其他人的代码编写的表格,并且您没有办法添加类型标识符字段,那么我没有给您一个通用的答案。我想您可以尝试将指针读出为不同的类型,然后看看哪些有效?

关于c++ - 取消引用指向未知类型变量的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12466485/

相关文章:

c++ - 为什么这个整数隐式转换不明确?

c++ - 尝试构建 boost 时更新 58 个目标失败,发生了什么?

c - 使用结构和数组的错误 int 值

mysql - 如何将字符串作为查询参数传递

c - int *val = otherVal 和 int val = otherVal 之间的指针差异

c++ - 为什么malloc不能在FreeBSD-x64内核空间分配大内存?

c++ - 我可以使用带符号的整数作为 __builtin_popcount() 的参数吗?

c++ - 用于从麦克风捕获声音并调节音量的 API

java - Hibernate:将 Double 作为 Int 保存到数据库

c++ - std::uninitialized_fill() 和 std::get_temporary_buffer()