指针转换为char *数组

时间:2016-10-05 11:03:00

标签: c++ pointers

我对C ++很陌生,而且我很难理解下面最后一行的内容:

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

所以htons返回一个u_short或WORD,但tBuf上的强制转换对我来说有点混乱。它是否符合“tBuf指向的值被转换为WORD指针并从htons分配返回”的内容?

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

1 个答案:

答案 0 :(得分:2)

这可能不是推荐的做法,但AFAIK,它是安全的。确实,通常,将指针指向P,将其转换为指向Q的指针并将其用作指向Q的指针会导致未定义的行为。这看起来更糟糕,因为已知char的对齐要求是最弱的。

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

  

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

因此,此行*(WORD*)tBuf = htons((WORD)numToSend);仅执行完美定义的操作:

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

      
        
    1. 整数类型的prvalue可以转换为另一个整数类型的prvalue ...

    2.   
    3. 如果目标类型是无符号的,则结果值是与源一致的最小无符号整数   整数(模2n,其中n是用于表示无符号类型的位数)

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

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

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

但是仍然允许将分配的数组作为字符数组访问,即使第一个字节现在包含WORD,因为根据所谓的严格别名规则 3.10 Lvalues,它是明确允许的。 rvalues [basic.lval]§10:

  

如果程序试图通过除了其中一个之外的glvalue访问对象的存储值   以下类型的行为未定义:
...
  (10.8) - char或unsigned char类型。

如果未通过新表达式获取tBuf指针,唯一正确的方法是memcpy

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

由于存储器足够大,所以允许使用任何指针,这就是我所说的推荐做法。