【问题标题】:Dereferencing a char pointer in C/C++?在 C/C++ 中取消引用 char 指针?
【发布时间】:2012-09-25 20:09:18
【问题描述】:

我正在使用 DWARF 和 ELF 信息的程序工作。我使用名为 Pin 的工具迷上了另一个程序。我有来自“Y”程序中声明的全局变量的地址,并将其连接到我将称为“X”的 Pin 模块中。

我得到了这些全局变量的一堆地址。不幸的是,当我尝试取消引用它们时遇到了麻烦。例如(现在我正在手动做事情,看看它是否在做应该做的事情):

char * limit, * address1;

for(address1 = (char *) 0x804A040, limit = address1 + bytesize; address1 < limit; address1++)
      cout <<  *(address1) << "\n";

我应该得到存储在那个地址中的变量,它是一个单词的char *。在这种情况下我是否必须取消引用两个指针?地址以及存储在该地址中的char *

当我想取消引用 int 变量时,这非常有效,但是每当我尝试取消引用 char 指针或变量时,我都会得到 non-ASCII 值...

【问题讨论】:

  • 您的for 语句只有两个分号分隔的参数,但需要三个才能有效。
  • 您希望打印字符串的地址还是字符串本身?
  • 您是要从当前进程还是单独进程中读取数据?
  • @PeteFordham 我期待自己得到字符串。我得到的字面意思是:@@�
  • 我正在尝试从 Pin 所连接的进程中读取数据,因此它将是由我的 Pin 模块 @AdamRosenfield 控制的“当前进程”

标签: c++ c pointers dereference variable-address


【解决方案1】:

这样想:如果要取消引用 int,请使用 int *

int *addr = (int *)0x12345678;
printf("%d\n", *addr);

但是一个字符串已经是一个指针,所以如果你这样做:

char *addr = (char *)0x12345678;

你不需要取消引用它来打印它,所以你可以这样得到它:

printf("%s\n", addr);

另外,假设你有这样的记忆:

00000001:  0x12345678
...
12345678:  'A'
12345679:  'B'
1234567A:  '\0'
...

让我们访问地址0x00000001,看看我们能做什么:

unsigned int *addr = (unsigned int *)0x00000001;

现在*addr 保存一个整数,它是我们字符串的第一个字符的地址。接受字符串参数的函数,通常要求字符串地址,即指向它的指针,因此*addr 也是我们应该在coutprintf 上打印的字符串。

// This should print "AB"
printf("%s\n", (char *)(*addr));

现在,如果您取消引用我们的值 (0x12345678),我们将获得字符串的第一个字符,并且只有它,作为 char。因此,如果您滥用它并将其取消引用到char *printf 将尝试搜索内存“A”,即0x00000041,并且可能会出现分段错误。

因此,取消引用其值、获取第一个字符的正确方法是:

// This should print "A"
printf("%c\n", (char)(**addr));

因此,作为结论,如果您仍然获得非 ASCII 值,这可能是地址之间的这种层次结构的问题,我建议您严格调试内存并查看是否创建指向指针的指针是你的字符串的正确路径。

【讨论】:

  • 我是这么想的,但是这样做时遇到了分段错误。我确实可以访问该虚拟内存空间,所以我不知道为什么会得到它。
  • 这真的很有帮助,非常感谢!我会尝试一下,让你知道会发生什么!谢谢@flaviotoribio 编辑:你确定这是正确的语法吗?由于指向指针的指针,编译器一直抱怨“一元 * 的类型参数无效”
  • 或许可以试试(char)(*(char *)*addr)。那是因为我使用了另一种类型的中间变量来进行取消引用。
  • 我设法通过将指针转换为char * 使其工作。 (char *) *(address1) 非常感谢!
【解决方案2】:

是的,您需要取消引用两个指针。首先获取保存 char* 的变量的地址,然后解除对 char* 的引用。

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2012-05-23
    • 2020-03-17
    相关资源
    最近更新 更多