将unsigned short *强制转换为unsigned int *

时间:2019-04-23 12:57:27

标签: c++

我正在学习c ++,并且对演员表有疑问。 我有一个无符号的short *,我想将其转换为一个无符号的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)

结果不同...有人可以解释我为什么以及如何解决这个问题吗?

非常感谢

3 个答案:

答案 0 :(得分:6)

在C ++中铸造一种指向另一种的指针,然后对其取消引用是“未定义的行为”;您将被禁止这样做并期望获得理智的结果。

在这种特定情况下,类型转换基本上是对指向的地址处的数据字节进行重新解释。在产生的机器代码级别上,问题是int在系统上需要4个字节,而short仅2个字节;因此您读了short末尾并获得了垃圾数据。

在比生成的机器代码更高的抽象水平上,还存在一些问题(上述未定义的行为不是的意思是“嗯,您读错了内存”,这是一种温和的可能性;确实疯狂的事情可以发生,包括时间旅行,这不是玩笑)。但这足够了。

当您将实际的int投射到short(或无符号等效项)时,该语言实际上会获取short的内容并将其扩展为填充int

无法获取unsigned short*,并且在不创建指向该资源的情况下获取unsigned int*

C ++中的指针就像街道地址。 int是一栋办公楼,short是一栋简易别墅。如果您有平房的地址,并且在其上写下“这是一栋办公楼”,那么它就不是真的。当有人去平房盲目地使用电梯时,事情就screwy去了。

另一方面,如果您有一个平房并说“将其建在办公楼中”(实际是一个int的缩写),则可以这样做。您将获得另一座建筑物(因为办公楼不适合平房使用),但它适合平房中的所有建筑物。

答案 1 :(得分:4)

unsigned short*指向内存中包含unsigned short类型的对象的位置。该内存位置不包含类型unsigned int的对象。通常,在指向的位置不存在该类型的对象时,通过指针间接指向一种类型的行为是不确定的(某些类型有例外)。

答案 2 :(得分:0)

您不能将指针转换为其他指针类型并期望它能工作。指针指向无符号short的存储位置。
如果需要强制转换,则必须从内存中拉出unsigned 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;