指针强制转换为char*数组

Pointer cast into char* array

本文关键字:char 数组 转换 指针      更新时间:2023-10-16

我对c++相当陌生,我很难理解下面最后一行发生了什么:

int numToSend = bs->GetSize();
char *  tBuf = new char[NUM_LENGTH_BYTES + numToSend];
*(WORD*)tBuf = htons((WORD)numToSend);

所以htons返回一个u_short或WORD,但是对buf的强制转换对我来说有点困惑。它是沿着"由tf指向的值被转换为一个WORD指针,并分配从返回"的线条吗?

我相信在大多数情况下这是一个相当不安全的操作,这里的最佳实践是什么?

这可能不是推荐的做法,但我敢肯定,这是安全的。一般来说,接受指向P的指针,将其转换为指向Q的指针,并将其用作指向Q的指针,会导致未定义的行为。这里看起来更糟,因为已知char的对齐要求是最弱的。

但是char * tBuf指针是通过一个新的表达式得到的。这样一个新的表达式在内部依赖于一个分配函数来获得存储,c++14的n4296草案在3.7.4.1分配函数[basic.stc.dynamic]中说。分配]§2:

分配函数尝试分配请求的存储量。如果它成功了,它将返回存储块的起始地址,该存储块的字节长度至少等于请求的尺寸…返回的指针应适当对齐,以便可以被转换指向具有基本对齐要求(3.11)的任何完整对象类型的指针,然后使用访问已分配存储中的对象或数组(直到通过调用显式释放存储为止)到相应的释放函数)

所以这行*(WORD*)tBuf = htons((WORD)numToSend);只做完美定义的操作:

  • numToSend从整数类型转换为无符号类型,4.7积分转换[conv.integral]表示:

    1. 一个整型的右值可以转换成另一个整型的右值

    2. 如果目的类型为无符号类型,则结果值为与源类型相同的最小无符号整数整数(对2n取模,其中n是用来表示无符号类型的位数)

  • 以WORD或uint16_t作为参数调用htons返回uint16_t或WORD

  • 将new获得的指针转换为WORD *,并使用该指针访问分配的存储空间中的对象

简单地说,分配的数组的前两个字节的值现在是未指定的。更确切地说,它是WORD在特定实现中的字节表示。

但是它仍然被允许作为字符数组访问分配的数组,即使第一个字节现在包含一个WORD,因为根据所谓的严格混叠规则 3.10左值和右值[basic]明确允许它。§10:

如果一个程序试图通过其他的glvalue来访问一个对象的存储值

(10.8) - char或unsigned char类型


如果tBuf指针没有通过new表达式获得,那么唯一正确的方法是执行memcpy:

WORD n_numToSend = htons(numToSend);
memcpy(tBuf, &n_numToSend, sizeof(WORD));

只要存储空间足够大,任何指针都可以使用

,这就是我所说的推荐做法。