将 unsigned short * 转换为 unsigned int *

Posted

技术标签:

【中文标题】将 unsigned short * 转换为 unsigned int *【英文标题】:Cast unsigned short * to unsigned int * 【发布时间】:2019-04-23 12:57:26 【问题描述】:

我正在学习 c++,我有一个关于演员表的问题。 我有一个 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)

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

非常感谢,

【问题讨论】:

unsigned short* 转换为unsigned int* 是危险的(嗯……未定义的行为)。为什么不(unsigned int)*a;?这会产生一个受支持的简单转换。 请注意,static_cast 甚至无法编译。 “如何解决这个问题”那里没有问题,你不能通过随机代码并期望它工作。 reinterpret_cast 的名字相当糟糕。它应该被称为danger_you_are_about_to_shoot_yourself_in_the_foot_unless_you_really_really_know_what_you_are_doing_cast 【参考方案1】:

在 C++ 中将一种指针转换为另一种指针,然后取消引用它是“未定义的行为”;不允许您这样做并期望得到合理的结果。

在这种特定情况下,强制转换基本上是对指向地址处的数据字节进行重新解释。问题是,在生成的机器代码级别上,int 在您的系统上需要 4 个字节,而 short 只有 2 个;所以你读完了short 的结尾并得到垃圾数据。

在比生成的机器代码更高的抽象上也存在问题(上述未定义行为不是意味着“好吧,你读错了内存”,这是一种温和的可能性;真正疯狂的事情可以发生,包括时间旅行,这不是开玩笑)。但这已经足够了。

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

没有办法获取unsigned short*,并且在不创建独立资源指向的情况下获取unsigned int*

C++ 中的指针就像街道地址。 int 是办公楼,short 是平房。如果你有一个平房的地址,你在上面乱写“这是一栋办公楼”,这并不成立。而当有人去平房并盲目使用电梯时,事情就会发生screwy。

另一方面,如果你有一个平房并说“把它建造成办公楼”(一个实际的短到 int 的转换),那是可以做到的。你会得到一个不同的建筑(因为办公楼不适合平房),但它适合平房的所有东西。


现在,通常允许您将指针转换为对齐较少的指针,只要在使用它们之前将指针转换回来(!)。

在某些狭窄的情况下,您可以取消引用指针。

    char* 可用于读取某些类型的“原始内存”(以及std::byte* 等)。

写入这样的字节来复制对象只有在它们“可简单复制”时才有效。

    在某些情况下,指向一种类型的前缀的指针可用于读取另一种类型。

这被称为“布局兼容”,并且规则具体且没有大多数人想象的那么宽宏大量。

【讨论】:

我认为还指出允许解除引用指向不同类型的指针(布局兼容类型、引用兼容类型)的场景会有所帮助跨度> 【参考方案2】:

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

【讨论】:

【参考方案3】:

您不能将指针转换为另一种指针类型并期望它工作。指针指向 unsigned 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;

【讨论】:

unsigned int b = static_cast&lt;unsigned int&gt;(*ptr_a); 可以是unsigned int b = *ptr_a;。另外你在unsigned int ptr_b = &amp;b;中有一个错字

以上是关于将 unsigned short * 转换为 unsigned int *的主要内容,如果未能解决你的问题,请参考以下文章

将 Long 转换为 Unsigned Short Int / Strtol

怎样把unsigned short 转换为 unsigned char

在 C++ 中将 unsigned char (byte) 数组转换为 unsigned short

short int 到 unsigned int 转换网络字节顺序 C++

如何在 C 中将 short 转换为 unsigned char *buf?

C ++:从wchar_t *转换为unsigned short *是否安全?