我正在学习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)。 感谢您的帮助。
答案 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;
您正在尝试访问该地址,该地址不在程序段中,从而导致分段错误。