reinterpret_cast如何工作?

时间:2017-07-24 11:50:54

标签: c++ byte binaryfiles reinterpret-cast

我想知道reinterpret_cast是如何在幕后工作的。我正在从一本书中学到它,但我只是不明白。 例如。假设我有以下部分代码:

int a = 255;
char *pChar = reinterpret_cast<char*>(&a);

std::string str = "Hello";
char *pChar = reinterpret_cast<char*>(&str);

pChar在两个例子中指出了什么,为什么当我尝试打印其内容时我看不到任何东西,当然reinterpret_cast如何工作?

修改 我知道reinterpret_cast使用起来非常危险,只想用它将字节直接写入内存块的二进制文件中。 我不明白的是,当我有一个

int a = 255; (00 00 00 FF in memory)

我希望将变量a视为一系列字节,char *:

char *pChar = reinterpret_cast<char*>(&a);

pChar会指向变量a(00 00 00 FF)的各个字节吗?

所以,当我想写入pChar指向的二进制文件时:

a_file.write(reinterpret_cast<char*>(&a), sizeof(a));

它写出变量a的各个字节,对吗?

2 个答案:

答案 0 :(得分:6)

它在运行时没有做任何事情。 Cpp reference

  

与static_cast不同,但与const_cast不同,是reinterpret_cast   表达式不会编译为任何CPU指令。这纯粹是一个   编译器指令,指示编译器处理序列   表达式的位(对象表示),就像它具有类型一样   NEW_TYPE。

你的转换都非常危险,因为第一个指针指向一个int,它可能在内存中表示为00 00 00 FF,因此不会打印任何东西,因为00 ==&#39; \ 0&# 39;,这是字符串结尾的char。这假设您使用的是大端机器。如果这是一个用非零值填充所有字节的int,那么您将无限期地读取该位置的末尾。

第二个告诉编译器将string所在的位置视为char*,这不是实际字符串内容的起始地址,而是实现定义的结构,其中包含大小,容量和指针变量或小字符串optmization的字符串表示。由于大小和容量通常为64位宽,并且大小和容量可能都小于2 ^ 32,因此您可能会遇到零字节,因此不会打印任何内容。再一次,如果没有意外的零字节,你的读取将无限期地结束。

解决OP的编辑:

根据链接的cpp-reference网站的第5部分

  

任何指向T1类型对象的指针都可以转换为指向对象的指针   另一种类型cv T2。这完全等同于static_cast(static_cast(expression))(这意味着如果T2&#39; s   对齐要求并不比T1的值更严格   指针不会改变并返回结果指针的转换   原始类型产生原始值)。无论如何,   如果允许的话,结果指针只能被安全地解除引用   类型别名规则(见下文)

如下所述:

  

指向动态类型为的对象的指针或引用   DynamicType是reinterpret_cast(或C样式转换)到指针或   引用不同类型AliasedType的对象,总是强制转换   成功,但结果指针或引用可能只用于   如果满足以下条件之一,则访问该对象:...

     

AliasedType是char,unsigned char或std :: byte:这允许   检查任何对象的对象表示作为数组   字节。 ...

,指针应指向a开始的地址。

答案 1 :(得分:0)

  

pChar在两个例子中都指出了什么?

它们将指向存储这些变量的内存的第一个字符。

  

为什么当我尝试打印其内容时,我无法看到任何内容

你可能以错误的方式做到这一点。您不能将它们打印为以空字符结尾的字符串(例如,a的内部表示包含0,这将被视为终止零。)

您可以这样打印:

for (size_t i=0; i<sizeof(int); i++) {
    printf("%02x ", pChar[i]);
}
printf("\n");

这将以十六进制打印a的字符值。这样,您就会看到ff 00 00 00(假设您使用的是小端机器)。

您可以对std::string执行相同的操作。您将看到std::string的内存表示。

(您可以使用&#34;%c&#34;将内容打印为char。如果将stdout重定向到文件,您将在文件中看到变量的内部表示。

  

当然reinterpret_cast如何运作?

它只是重新解释它的参数,假装它有另一种类型。不涉及运行时成本(注意:这种解释非常简化)。

  

pChar是否指向变量a(00 00 00 FF)的各个字节?

是的,假设char是一个字节,而你是一个大端机器。

  

它写入变量a,右

的各个字节

是的,但可能你也可以在没有任何reinterpret_cast的情况下做同样的事情,这里不需要它(假设a_file.write的第一个参数是void *