Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 取消引用指向未知类型变量的指针_C++_C_Memory - Fatal编程技术网

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

C++ 取消引用指向未知类型变量的指针,c++,c,memory,C++,C,Memory,我不知道如何确切地解释我现在遇到的问题,如果我在问题的标题上含糊不清,那么很抱歉 我现在拥有的是存储在变量中的虚拟地址列表。例如,我有 0x8c334dd 存储在char变量中。此地址是另一个包含数据的变量的地址。我想做的是去那个地址,获取存储在上面的数据 我的假设是取消对指针的引用是最好的方法,不幸的是,我不知道地址指向的变量的类型,那么在这种情况下取消引用是如何工作的呢?我无法执行:*(char*)8c334dd,因为我不知道地址指向的变量类型 如果我将它转换为(int*),我会得到一些地址

我不知道如何确切地解释我现在遇到的问题,如果我在问题的标题上含糊不清,那么很抱歉

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

0x8c334dd

存储在char变量中。此地址是另一个包含数据的变量的地址。我想做的是去那个地址,获取存储在上面的数据


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

如果我将它转换为
(int*)
,我会得到一些地址指向的变量的一些数据(记住我有几个地址),但对于其他的,我只是得到一个地址,我需要数据(这些变量是structs、chars等)


我使用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
之前)。此外,对于
调试
生成,您可以检查签名字段
sig
是否包含某些特定的签名值。(这意味着您的init代码到init a
VAR
实例需要始终设置
sig
字段。)

如果您执行类似的操作,那么如何初始化它?运行时代码将始终有效:

VAR v;

#ifdef DEBUG
v.sig = VAR_SIG;
#endif // DEBUG
v.type = vartypeFloat;
v.data = 3.14f;
如果您想在编译时初始化它呢?如果您想用整数值初始化它,这很容易,因为
int
类型是
联合中的第一个类型:

VAR v =
{
    vartypeInt,
#ifdef DEBUG
    VAR_SIG,
#endif // DEBUG
    1234
};
如果您使用的是C99兼容版本的C,那么实际上可以使用字段名初始化结构,并让它指定任何类型。但是Microsoft C不兼容C99,因此如果要使用
float
double
值初始化结构,上述操作将是一场噩梦。(如果将浮点值强制转换为整数,C不仅会更改类型,还会对值进行四舍五入;而且我知道,在C程序中,没有任何技巧可以通过移植获得一个在编译时正确表示32位浮点的32位整数值。)

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


如果您正在阅读由其他人的代码编写的表,并且您没有添加类型标识符字段的方法,那么我没有一个通用的答案。我想你可以试着把指针读成不同的类型,看看哪种类型有效?

只是想添加一些东西,对于那些使用ELF符号表的人来说,我发现DWARF文件中的模具更容易使用。您可以使用DWARF而不是ELF来获取变量的地址、类型和名称,并且libdwarf有很好的文档。

假设您对地址有读取权限:
char a=*(char*)0x8c334dd我的假设是取消引用指针在这里不起作用,因为如果我取消引用一个具有地址的变量,那么我将得到它的内容(与地址相同),而不是第二个变量的内容,对吗?我也不知道我想从哪种类型的变量中获取数据,嗯?什么是“第二个变量”?如果取消对指针的引用,则会得到存储在该地址的内容。(如果这是一个C问题,为什么它被标记为C++?)HMM,所以假设我有VAR1,即:int数据=34;然后我有另一个变量var2=“0x8f3343d3”,这是一个指向该变量的地址。我的问题是,如果我这样做*(var2),我会从数据var中获取“0x8f3343d3”值还是34?更具体地说,var2的工作原理与指针相同吗?即使未声明为指针?@user1106581,也只能对指针使用
*
。但在应用
*
之前,可以将
var2
强制转换为
int*
。这很有帮助。给了我一些好主意。不幸的是,我没有给出表中的值。我正在使用ELF符号表值,这是一种“反编译”传递给我的程序的方法。通过给我ELF符号表,我需要能够推断哪些变量是int类型、char类型或struct类型的,然后获取每个变量的值。到目前为止,我得到的是一个地址,它指向一个未知类型的“某处”,这正是我们可以从elf符号表中获得的地址集。我确实在使用其他人的表,更确切地说是elf提供的API。问题是,试图猜测指针的类型将是徒劳的,因为编译器不会抱怨类型无效,所以如果我试图以字符的形式读取指针,那么我可能会得到一个随机的非ASCII字符值,如果我尝试以int的形式读取它,我可能会得到实际值或只是指向该值的另一个地址。。