【问题标题】:Placing uint32_t into array of uint8_t将 uint32_t 放入 uint8_t 数组
【发布时间】:2013-12-10 00:36:40
【问题描述】:

所以我有以下代码:

uint32_t length = 1;
uint8_t buffer[5];

buffer[0] = htonl(length);

std::cout << (uint32_t)*buffer << std::endl;
std::cout << htonl(length) << std::endl;

倒数第二行打印出0,最后一行打印出16777216.....why....?

【问题讨论】:

  • 您似乎没有在初始化缓冲区。为什么不呢?
  • 其实我才意识到,你只初始化buffer[0]
  • @Ethan 与其展示这个最糟糕的实践代码,不如告诉我们您要解决的实际问题可能更有成效。
  • 问题解决了。只是一直以为这行不行,不知道为什么不行。

标签: c++ sockets uint


【解决方案1】:

您实际上并没有将uint32_t 放入uint8_ts 的数组中。相反,您将其放在buffer[0] 中。由于长度要大得多,因此只会存储最低的 8 个字节。而且由于您调用了htonl(length),因此最低 8 个字节实际上都是 0(至少如果您的主机系统使用与网络不同的字节顺序 - 这里似乎就是这种情况)。

如果你真的想使用buffer 的前四个元素来存储length,你必须告诉编译器将它们重新解释为uint32_t

uint32_t length = 1;
uint8_t buffer[5];

(uint32_t&)*buffer = htonl(length);

std::cout << (uint32_t)*buffer << std::endl;
std::cout << htonl(length) << std::endl;

虽然这不是一个好主意..

【讨论】:

  • 我一直认为在 C 中你可以做这样的事情。它只会溢出到数组的其余部分......但是我正在使用 C++ 进行编译。 C++ 有区别吗?
  • 在 C 中也是一样的。如果你写了int i = 10000000000UL,编译器会将值“剪切”到合适的大小以将其存储在里面。像这样的作业永远不会溢出到其他内存中。使用(uint32_t&amp;),我告诉编译器将buffer 指向的内存区域视为uint32_t,这样它就可以在不削减它的情况下存储该值。
【解决方案2】:

倒数第二行巧合地打印出零——您从未在buffer 中存储任何内容。您将 buffer[0] 设置为一个不适合该位置的值,而其余部分未初始化。

最后一行打印出 16,777,216,因为您的平台是 little-endian 并且htonl 切换到 big-endian 格式,所以您的 0,0,0,1 变为 1,0,0,0。那是 256^3 位置的一个,1 * 256^3 = 16,777,216。

【讨论】:

  • 第一段不正确。他存储在buffer[0]cout 中,他取消了buffer 的引用,这给了他数组的第一个元素。它打印 0,因为他调用了 htol(),它切换字节顺序并导致低 8 个字节(复制到 buffer[0])为 0。
猜你喜欢
  • 2020-04-15
  • 1970-01-01
  • 2011-04-10
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
  • 2017-06-13
  • 1970-01-01
相关资源
最近更新 更多