关于reinterpret_cast和指针

时间:2018-09-18 09:19:55

标签: c++ pointers casting

我正在学习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。但是似乎错误是“意味着您试图访问您无法访问的内存”。 (Erci Finn)。 感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

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

的用法
  

8.5.1.10重新解释演员表
  ...
  5. 整数类型或枚举类型的值可以显式转换为指针。指针将转换为足够大的整数(如果实现中存在这样的大小)并返回相同的指针类型,则指针将具有其原始值;指针和整数之间的映射否则由实现定义。 [ 注意:   除6.6.4.4.3中所述的以外,此类转换的结果将不是安全得出的指针值。 —尾注]

并且:

  

6.6.4.4.3安全衍生的指针[basic.stc.dynamic.safety]
  ...
  2. 指针值只有在具有对象指针类型并且是以下其中之一时,才是安全地指向动态对象的指针:

  (2.1)—调用:: operator new(std :: size_t)或:: operator new(std :: size_t,std :: align_val_t)的C ++标准库实现的返回值;
  (2.2)—取由左值指定的对象(或其子对象之一)的地址的结果,该左值是通过安全派生的指针值进行间接寻址而产生的;
  (2.3)—使用安全得出的指针值进行的明确定义的指针算法的结果;
  (2.4)—对安全派生的指针值进行明确定义的指针转换的结果;
  (2.5)—对安全派生的指针值进行reinterpret_cast的结果;
  (2.6)-重新解释安全地得出的指针值的整数表示形式的结果;

  (2.7)—一个对象的值,其值是从可追溯的指针对象复制而来的,其中在复制时,源对象包含一个安全派生的指针值的副本。

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

答案 1 :(得分:2)

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

有效使用指针的示例是

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

这会将x的地址放入px

std::cout << px;

将输出地址。

std::cout << *px;

将输出x的值。

答案 2 :(得分:2)

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

k : 0x4e20
Segmentation fault

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

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

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