[英]Cast unsigned short * to unsigned int *
我正在学习 C++,我有一个关于 cast 的问题。 我有一个 unsigned short * 我想把它转换成一个 unsigned int * 但我没有相同的值,我想知道为什么。
当我将一个 short 转换为一个 int(使用静态转换)时,我具有相同的值,但它不适用于 unsigned short * 到 unsigned int *
所以我试着理解为什么,一个 short 是 4 个字节,一个 int 可以是 8. 16 或 32? 所以指针每次都会进入内存? 但是为什么从 short 转换为 int 有效呢?
unsigned short *a = something(); // something return me a unsigned short *a
unsigned int *b = static_cast<unsigned int *>(a); // I also tried with reintepret_cast
std::cout << *a << std::endl // (print me my first value)
std::cout << *b << std::endl // (print me a wrong value)
结果不同......有人可以解释我为什么以及如何解决这个问题吗?
非常感谢,
在 C++ 中将一种指针转换为另一种然后取消引用它是“未定义的行为”; 你不被允许这样做并期待理智的结果。
在这种特定情况下,强制转换基本上是对指向的地址处的数据字节进行重新解释。 在生成的机器代码级别,问题在于int
在您的系统上需要 4 个字节,而short
仅为 2 个; 所以你阅读了short
的结尾并获得了垃圾数据。
在比生成的机器代码更高的抽象上也存在问题(上述未定义行为并不意味着“好吧,你读错了内存”,这是一种温和的可能性;真正疯狂的事情可能会发生,包括时间旅行,但这不是笑话)。 但这就足够了。
当您将实际的int
转换为short
(或无符号的等价物)时,该语言实际上采用short
的内容并将其扩展以填充int
。
没有办法采用unsigned short*
并且在不创建指向的独立资源的情况下获得unsigned int*
。
C++ 中的指针就像街道地址。 int
是写字楼, short
是平房。 如果你有一间平房的地址,然后在上面潦草地写上“这是一栋办公楼”,那是不真实的。 而当有人去平房盲目地使用电梯时,事情就变得不对劲了。
另一方面,如果你有一座平房,并说“把它建成办公楼”(一个实际的 short 到 int 的转换),那是可以做到的。 你得到一栋不同的建筑(因为办公楼不适合平房),但它适合平房的所有东西。
现在,通常允许您将指针转换为对齐程度较低的指针,只要您在使用它们之前将指针转换回来 (.)。
在某些狭窄的情况下,您可以取消引用指针。
char*
可用于读取某些类型(以及std::byte*
等)的“原始内存”。写入此类字节以复制对象仅在它们“可平凡复制”时才有效。
这就是所谓的“布局兼容”,规则比大多数人想象的更具体、更宽松。
unsigned short*
指向内存中包含类型为unsigned short
的对象的位置。 该内存位置不包含unsigned int
类型的对象。 当指向的位置不存在该类型的对象时,通过指向该类型的指针进行间接访问的行为通常是未定义的(某些类型有例外)。
您不能将指针转换为另一种指针类型并期望它起作用。 指针指向 unsigned short 的内存位置。
如果您需要转换,那么您必须将未签名的 short 从内存中拉出并将其放入另一个内存中。
// in main
unsigned short *ptr_a = something(); // something return me a unsigned short *a
unsigned int b = static_cast<unsigned int>(*ptr_a); // cast the object at a into an uint
unsigned int ptr_b = b&; // get the address for the new object
std::cout << *ptr_a << std::endl;
std::cout << *ptr_b << std::endl;
但是,当您从函数返回指针时,您不能使用堆栈上对象的地址(如本例中的 b&),而是需要使用new
。 在这种情况下,您应该确保您也调用了delete
int* something() {
// int a = 5;
// BAD - DON'T DO THIS: return a&;
int* a = new int;
*a = 5;
return a; // OK, but remember to delete
}
// in some function, eg. main
unsigned short *ptr_a = something(); // something return me a unsigned short *a
unsigned int *ptr_b = new int;
*ptr_b = static_cast<unsigned int>(*ptr_a);
std::cout << *ptr_a << std::endl;
std::cout << *ptr_b << std::endl;
delete ptr_a;
delete ptr_b;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.