在获得4字节int的长度后,尝试预先挂起2字节的消息长度。我使用memcpy复制int的2个字节。当我查看我复制的第二个字节时,它是预期的,但访问第一个字节实际上打印了4个字节。
我希望dest [0]和dest [1]都包含int的1个字节。无论它是一个重要的字节,还是顺序被切换......我可以在memcpy上抛出一个偏移量或者反转0和1.它不必是可移植的,我只是想它可以工作。
Windows中使用LoadRunner和Ubuntu使用GCC也会发生同样的错误 - 所以我至少试图排除可移植性。
我不确定我哪里出错了。我怀疑这与我最近没有使用指针有关?有没有更好的方法将int转换为short,然后将其放在缓冲区的前2个字节中?
char* src;
char* dest;
int len = 2753; // Hex - AC1
src=(char*)malloc(len);
dest=(char*)malloc(len+2);
memcpy(dest, &len, 2);
memcpy(dest+2, src, len);
printf("dest[0]: %02x", dest[0]);
// expected result: c1
// actual result: ffffffc1
printf("dest[1]: %02x", dest[1]);
// expected result: 0a
// actual result: 0a
答案 0 :(得分:2)
你不能只从一个四字节对象中取一个随机的两个字节,并将其称为一个简短的转换。
在执行memcpy之前,您需要将int复制到两个字节的int中。
但实际上,这也不是最好的方法,因为你无法控制整数的字节顺序。
您的代码应如下所示:
dest[0] = ((unsigned)len >> 8) & 0xFF;
dest[1] = ((unsigned)len) & 0xFF;
那应该用网络字节顺序写出来,也就是大端。所有标准网络协议都使用此字节顺序。
我还要添加以下内容:
assert( ((unsigned)len & 0xFFFF0000) == 0 ); // should be nothing in the high bytes
答案 1 :(得分:2)
首先,您错误地使用了printf
。此
printf("dest[0]: %02x", dest[0]);
在x
中使用printf
格式说明符。 x
格式说明符需要类型为unsigned int
的参数。不是char
,而是unsigned int
,只有unsigned int
(或者int
具有非负值)。
您提供的即时参数的类型为char
,可能已在您的平台上签名。这意味着您的dest[0]
包含-63
。类型为char
的可变参数会自动提升为int
类型,这会将0xc1
转换为0xffffffc1
(作为-63
中已签名的int
表示形式}})。由于printf
需要unsigned int
值而您传递的是负int
值,因此行为未定义。您看到的打印输出只不过是未定义行为的表现。这没有意义。
在这种情况下打印dest[0]
的一种正确方法是
printf("dest[0]: %02x", (unsigned) dest[0]);
我非常确定输出仍为ffffffc1
,但在这种情况下,0xffffffc1
是从负-63
值到{{1}的整数转换的完美预期结果}类型。这里没什么不寻常的。
或者你可以做
unsigned int
应该为您提供所需的printf("dest[0]: %02x", (unsigned char) dest[0]);
输出。请注意,转换为c1
也会发生在这种情况下,但由于原始值为正(int
),因此转换为193
的结果也是正值int
1}}正常工作。
最后,如果您想直接使用原始内存,从一开始就使用正确的类型printf
。不是unsigned char
,而是char
。
其次,类型unsigned char
的对象可能容易占用两个以上的8位字节。根据平台,int
和0xA
值可能最终位于该0xC1
对象占用的内存区域的完全不同的部分。您不应期望复制int
对象的前两个字节将专门复制int
部分。
答案 2 :(得分:0)
你假设" int"是两个字节。你有什么理由呢?您的代码非常难以移植。
你做了另一个假设" char"没有签名。你有什么理由呢?同样,您的代码非常难以移植。
您对int中的字节顺序做了另一个假设。你有什么理由呢?同样,您的代码非常难以移植。
答案 3 :(得分:0)
而不是文字2,使用sizeof(int)。永远不要硬编码类型的大小。
如果此代码应该是可移植的,则不应使用int,而应使用固定大小的数据类型。
如果您需要16位,则可以使用int16_t
。
此外,字符的打印需要转换为无符号。现在,char被上传到int,并且符号被扩展。这给出了初始的FFFF