在我正在阅读的c ++代码中,发现了以下内容。 任何人都可以帮助我理解以下陈述的作用吗?
char buffer[4096];
// some code
int size = *(int*)(buffer);
答案 0 :(得分:14)
char buffer[4096];//this is an array of 4096 characters
// some code
int size = *(int*)(buffer);
将(衰减的)字符指针(buffer
)强制转换为整数指针。然后取消引用它以获得整数值。您从中获得的整数值将由buffer
数组的前4个字符值组成,假设您的机器中int
的大小为4个字节,或者通常由{{1组成字符。
换句话说,sizeof(int)
数组的第一个sizeof(int)
字符的内存表示将被视为表示单个整数值,因为现在它被整数指针指向,并且当取消引用该整数指针时,它将存储在buffer
整数变量中。
话虽如此,正如在评论部分反复说明的那样,这段代码是不安全的。有一点我想到的是,有些CPU有严格的对齐要求(参见this answer),在这种情况下,无法保证size
数组的第一个元素的地址符合整数的对齐要求导致这些CPU中的未定义操作。
请参阅@Lundin答案,了解更多原因导致此代码不安全,并且可能无法为您提供所需的结果。
答案 1 :(得分:6)
TL; DR:这段代码很糟糕,忘掉它并继续前进。
(buffer)
这个括号表示程序员对自己的编程能力不安全。
由于buffer
是一个字符数组,因此使用标识符buffer
会为您提供指向第一个元素的指针:char
指针。
(int*)
这是一个强制转换,将char
指针转换为int
指针。
*
获取该整数指针的内容,结果存储在整数size
中。
请注意,此代码完全不安全。许多指针转换会调用定义不明确的行为。可能存在对齐问题。可能存在指针别名问题(Google"严格别名规则")。此特定代码也依赖于endianess,这意味着它要求字符数组的内容具有给定的字节顺序。
总体而言,在执行此类操作时,使用int
或char
等签名类型(可能已签名)没有任何意义。特别是,char
类型非常有问题,因为它具有实现定义的签名,应该避免。请改用unsigned char
或uint8_t
。
稍差的代码看起来会像这样:
#include <stdint.h>
uint8_t buffer[4096];
// some code
uint32_t size = *(uint32_t*)buffer;
答案 2 :(得分:3)
任何人都可以帮助我理解以下陈述的作用吗?
第一句话:
char buffer[4096];
声明一个大小为chars
的{{1}}数组。
第二个陈述:
4096
1。首先将衰减的字符指针指向数组int size = *(int*)(buffer);
(也称为buffer
),这是一个指向其第一个元素的指针,当时设置其声明
2. 然后将其转换为指向buffer
或int
3。最后,将此指针的内容(类型为int*
)分配给变量int
。
答案 3 :(得分:1)
它需要buffer[0]
的地址,将其转换为int*
,取消引用,然后使用解除引用的值初始化size
。换句话说,它需要sizeof(int)
的第一个buffer
字节,假装这些字节是int
,并将该值存储在size
中。