如果代码尝试发送超过 37 个字节,那么它将发送未初始化的内存。如果它试图发送超过 512 个字节,那么它正在读取超出缓冲区的末尾。在任何一种情况下,都可能会发送内存垃圾模式。
Sendingdata_ 缓冲区为 512 字节,但其中只有 37 个字节已初始化。
char Sendingdata_[512]; // 512 unitialized values.
std::string finalHex = string-literal; // 36 ASCII characters + null termination.
strcpy(Sendingdata_, finalHex.c_str()); // 37 characters copied
boost::asio::async_write(..., boost::asio::buffer(Sendingdata_, bytes_transferred), ...);
finalHex 字符串被提供了一个字符串文字。例如,将字符串字面值"2400bb" 分配给字符串,将存储'2'、'4'、'0'、'0'、'b' 和'b' ASCII 字符。
std::string ascii = "2400bb";
assert(ascii.length() == 6);
assert('2' == ascii[0]);
assert('4' == ascii[1]);
assert('0' == ascii[2]);
assert('0' == ascii[3]);
assert('b' == ascii[4]);
assert('b' == ascii[5]);
考虑使用向量,以十六进制表示法提供数值:
std::vector<unsigned char> hex = { 0x24, 0x00, 0xbb };
assert(hex.size() == 3);
assert(0x24 == hex[0]);
assert(0x00 == hex[1]);
assert(0xbb == hex[2]);
或者,可以通过提供\x 控制字符来使用std::string 来指示后续值是十六进制。但是,在解释值时可能需要执行显式转换,并使用处理字符串中的空字符的构造函数:
std::string hex("\x24\x00\xbb", 3);
// alternatively: std::string hex{ 0x24, 0x00, static_cast<char>(0xbb) };
assert(hex.size() == 3);
assert(0x24 == static_cast<unsigned char>(hex[0]));
assert(0x00 == static_cast<unsigned char>(hex[1]));
assert(0xbb == static_cast<unsigned char>(hex[2]));
这里是一个例子demonstrating的区别和Asio缓冲区的使用:
#include <cassert>
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <boost/asio.hpp>
int main()
{
// String-literial.
std::string ascii = "2400bb";
assert(ascii.length() == 6);
assert('2' == ascii[0]);
assert('4' == ascii[1]);
assert('0' == ascii[2]);
assert('0' == ascii[3]);
assert('b' == ascii[4]);
assert('b' == ascii[5]);
// Verify asio buffers.
auto ascii_buffer = boost::asio::buffer(ascii);
assert(ascii.length() == boost::asio::buffer_size(ascii_buffer));
assert(std::equal(
boost::asio::buffers_begin(ascii_buffer),
boost::asio::buffers_end(ascii_buffer),
std::begin(ascii)));
// Hex values.
std::vector<unsigned char> hex = { 0x24, 0x00, 0xbb };
// alternatively: unsigned char hex[] = { 0x24, 0x00, 0xbb };
assert(hex.size() == 3);
assert(0x24 == hex[0]);
assert(0x00 == hex[1]);
assert(0xbb == hex[2]);
// Verify asio buffers.
auto hex_buffer = boost::asio::buffer(hex);
assert(hex.size() == boost::asio::buffer_size(hex_buffer));
assert(std::equal(
boost::asio::buffers_begin(hex_buffer),
boost::asio::buffers_end(hex_buffer),
std::begin(hex),
std::equal_to<unsigned char>()));
// String with hex. As 0x00 is in the string, the string(char*) constructor
// cannot be used.
std::string hex2("\x24\x00\xbb", 3);
// alternatively: std::string hex2{ 0x24, 0x00, static_cast<char>(0xbb) };
assert(hex2.size() == 3);
assert(0x24 == static_cast<unsigned char>(hex2[0]));
assert(0x00 == static_cast<unsigned char>(hex2[1]));
assert(0xbb == static_cast<unsigned char>(hex2[2]));
}