关于reinterpret_cast和指针

About reinterpret_cast and pointer

本文关键字:指针 cast reinterpret 关于      更新时间:2023-10-16

我正在学习C和C++。 在此程序中:

#include <iostream>
int main() {
const int g = 10;
int * k = reinterpret_cast <int *> (20000); //ok
std::cout << "k : " << k  << std::endl;
std::cout << "* k : " << * k << std::endl;
* k = g;
std::cout << "* k : " << *k << std::endl;
return 0;
}

./converForTyEn
k : 0x4e20 分段故障(核心转储(

我预计 20000 然后是 10。但似乎错误是"意味着您试图访问无法访问的内存"。(埃尔奇·芬恩(。 谢谢你的帮助。

标准(N4713(的工作草案规定了

8.5.1.10 重新诠释演员表

5.整型或枚举类型的值可以显式转换为指针。转换为足够大小的整数(如果实现中存在任何此类整数(并返回到相同指针类型的指针将具有其原始值;指针和整数之间的映射由实现定义。[ 注:除6.6.4.4.3中所述外,这种转换的结果将不是安全派生的指针值。—尾注 ]

和:

6.6.4.4.3 安全派生的指针 [basic.stc.dynamic.safety]
...2. 仅当指针值
具有对象指针类型并且是以下之一时,指针值才是指向动态对象的安全派生指针:(2.1( — 调用 ::运算符 new(std::size_t( 或 ::
运算符 new(std::size_t, std::align_val_t( 的C++标准库实现返回的值;
(2.2( — 获取由左值指定的对象(或其子对象之一(的地址的结果,该地址是通过安全派生的指针值进行间接寻址而产生的;
(2.3( — 使用安全派生的指针值进行明确定义的指针算法的结果;
(2.4( — 安全派生的指针值的明确定义的指针转换的结果;
(2.5( — 安全派生的指针值reinterpret_cast的结果;
(2.6( — 安全派生指针值的整数表示reinterpret_cast的结果;

(2.7( — 其值是从可跟踪指针对象复制的对象的值,在复制时,源对象包含安全派生的指针值的副本。

由于您在整数文字(20000(上使用reinterpret_cast,因此转换的结果不是安全派生的指针值。尝试取消引用此类指针值会导致未定义的行为。

指针必须指向要使用的有效内存。在您的情况下,您可以将其设置为任意内存位置 20000。

有效指针用法的一个示例是

int x = 42;
int *px = &x;

这会将x的地址置于px

std::cout << px;

将输出地址。

std::cout << *px;

将输出x的值。

代码调用未定义的行为 (UB(,可能的输出为:

k : 0x4e20
Segmentation fault

其中第一行是k的地址。然后,在以下代码行中:

std::cout << "* k : " << * k << std::endl;

您正在尝试访问此地址,该地址不在程序的段中,从而导致分段错误。