*(int*)(缓冲区)是什么意思?

sha*_*ikh 6 c c++ pointers

在我正在阅读的c ++代码中,发现了以下内容.任何人都可以帮助我理解以下陈述的作用吗?

char buffer[4096];
// some code
int size = *(int*)(buffer);
Run Code Online (Sandbox Code Playgroud)

Bir*_*ebe 14

char buffer[4096];//this is an array of 4096 characters
// some code

int size = *(int*)(buffer);
Run Code Online (Sandbox Code Playgroud)

将(衰变的)字符指针buffer转换为整数指针.然后它取消引用它以获得整数值.从中获得的整数值将由buffer数组的前4个字符值组成,假设int您的机器中的大小为4个字节,或者通常由sizeof(int)字符组成.

换句话说,数组的第一个sizeof(int)字符的内存表示buffer将被视为表示单个整数值,因为现在它由一个整数指针指向,并且size当该整数指针时将存储在整数变量中被解除引用.

话虽如此,正如评论部分反复说明的那样,这段代码是不安全的.有一点我想到的是,有些CPU有严格的对齐要求(参见这个答案),在这种情况下,不能保证buffer数组的第一个元素的地址符合整数的对齐要求,导致未定义这些CPU中的操作.

请参阅@Lundin答案,了解更多原因,为什么此代码不安全,可能无法提供您正在寻找的结果.


Lun*_*din 6

TL; DR:这段代码很糟糕,忘了它并继续前进.


(buffer) 这个括号表示程序员对自己的编程能力不安全.

由于buffer是一个字符数组,因此使用标识符可以buffer为您提供指向第一个元素的char指针:指针.

(int*)这是一个转换,将char指针转换为int指针.

*获取该整数指针的内容,结果存储在整数中size.

请注意,此代码完全不安全.许多指针转换会调用定义不明确的行为.可能存在对齐问题.可能存在指针别名问题(Google"严格别名规则").此特定代码也依赖于endianess,这意味着它要求字符数组的内容具有给定的字节顺序.

总的来说,在执行此类操作时,使用像(intchar签名)这样的签名类型没有任何意义.特别是,char类型是非常有问题的,因为它具有实现定义的签名,应该避免.使用unsigned charuint8_t代替.

稍差的代码看起来像这样:

#include <stdint.h>

uint8_t buffer[4096];
// some code
uint32_t size = *(uint32_t*)buffer;
Run Code Online (Sandbox Code Playgroud)

  • 我认为你的示例代码根本不应该使用指针解引用技巧.使用`memcpy`仍然会有可能的字节序问题,但至少不会有UB. (5认同)