简体   繁体   English

关于reinterpret_cast和指针

[英]About reinterpret_cast and pointer

I am learning C and C++. 我正在学习C和C ++。 In this program: 在这个计划中:

#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 ./converForTyEn
k : 0x4e20 Segmentation fault (core dumped) k:0x4e20分段错误(核心转储)

I expect 20000 and then 10. But it seems that the error is "means that you tried to access memory that you do not have access to." 我希望20000然后是10.但似乎错误是“意味着你试图访问你无法访问的内存。” (Erci Finn). (Erci Finn)。 Thank for help. 谢谢你的帮助。

The working draft of the standard (N4713) states regarding the usage of 该标准的工作草案(N4713)陈述了关于使用的标准

8.5.1.10 Reinterpret cast 8.5.1.10重新解释强制转换
... ...
5. A value of integral type or enumeration type can be explicitly converted to a pointer . 5. 可以将整数类型或枚举类型的值显式转换为指针 A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; 转换为足够大小的整数(如果实现上存在任何此类)并返回相同指针类型的指针将具有其原始值; mappings between pointers and integers are otherwise implementation-defined. 指针和整数之间的映射在其他方面是实现定义的。 [ Note: Except as described in 6.6.4.4.3, the result of such a conversion will not be a safely-derived pointer value . [注意: 除6.6.4.4.3中描述的情况外,这种转换的结果不是安全派生的指针值 —end note ] - 尾注]

And: 和:

6.6.4.4.3 Safely-derived pointers [basic.stc.dynamic.safety] 6.6.4.4.3安全派生指针[basic.stc.dynamic.safety]
... ...
2. A pointer value is a safely-derived pointer to a dynamic object only if it has an object pointer type and it is one of the following : 2. 指针值是指向动态对象的安全派生指针,只有它具有对象指针类型且它是以下之一
(2.1) — the value returned by a call to the C++ standard library implementation of ::operator new(std::size_t) or ::operator new(std::size_t, std::align_val_t); (2.1) - 调用:: operator new(std :: size_t)或:: operator new(std :: size_t,std :: align_val_t)的C ++标准库实现返回的值;
(2.2) — the result of taking the address of an object (or one of its subobjects) designated by an lvalue resulting from indirection through a safely-derived pointer value; (2.2) - 通过安全导出的指针值获取由间接导致的左值指定的对象(或其子对象之一)的地址的结果;
(2.3) — the result of well-defined pointer arithmetic using a safely-derived pointer value; (2.3) - 使用安全派生的指针值定义良好的指针算法的结果;
(2.4) — the result of a well-defined pointer conversion of a safely-derived pointer value; (2.4) - 安全派生指针值的明确定义的指针转换结果;
(2.5) — the result of a reinterpret_cast of a safely-derived pointer value; (2.5) - 安全派生指针值的reinterpret_cast的结果;
(2.6) — the result of a reinterpret_cast of an integer representation of a safely-derived pointer value; (2.6) - 对安全派生的指针值的整数表示的reinterpret_cast的结果;
(2.7) — the value of an object whose value was copied from a traceable pointer object, where at the time of the copy the source object contained a copy of a safely-derived pointer value. (2.7) - 从可跟踪指针对象复制其值的对象的值,其中在复制时源对象包含安全派生的指针值的副本。

Since you are using reinterpret_cast on an integer literal ( 20000 ), the result of the conversion is not a safely-derived pointer value. 由于您在整数文字( 20000 )上使用reinterpret_cast ,因此转换的结果不是安全派生的指针值。 Attempting to dereference such a pointer value results in undefined behavior. 尝试取消引用此类指针值会导致未定义的行为。

A pointer must point to valid memory to be used. 指针必须指向要使用的有效内存。 In your case you set it to an arbitrary memory location, 20000. 在您的情况下,您将其设置为任意内存位置,20000。

An example of valid pointer usage would be 有效指针使用的一个例子是

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

This puts the address of x into px . 这将x的地址放入px

std::cout << px;

Would output the address. 会输出地址。

std::cout << *px;

Would output the value of x . 会输出x的值。

Your code invokes Undefined Behavior (UB), and a likely output would be: 您的代码调用未定义的行为(UB),可能的输出将是:

k : 0x4e20
Segmentation fault

where the first line is the address of k . 其中第一行是k的地址。 Then, in this line of code: 然后,在这行代码中:

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

you are trying to access this address, which is out of the segment of your program, thus causing a segmentation fault. 您正在尝试访问此地址,该地址不在您的程序段中,从而导致分段错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM