我正在做一个项目,从收到的字节构造一个对象MyClass。字节字符串由一个整数(4 个字节(后跟一条消息(5 个字节(组成。
我创建了一个模板类,以便能够轻松读取多种类型,并且还编写了一个模板专用函数来处理 char 数组的情况。
下面是可复制粘贴到主文件中的代码.cpp。
#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>
template <typename T>
class ByteReaderT {
public:
static const char* read(const char* source, T& dest, size_t sz)
{
std::copy(source, source + sz, &dest);
return source + sz;
}
};
template<>
inline const char* ByteReaderT<char*>::read(const char* source, char*& dest, size_t sz)
{
return std::copy(source, source + sz, dest);
}
#define DATA_SIZE 5
struct MyClass {
int num;
char* data;
MyClass(): num(0), data(new char[DATA_SIZE]) {}
void read(const char* str) {
// data is still alive and well
str = ByteReaderT<int>::read(str, num, sizeof(int));
// data is gone (data = nullptr)
// I need to reallocate memory with data = new char[DATA_SIZE];
str = ByteReaderT<char*>::read(str, data, DATA_SIZE);
}
};
int main()
{
char received_arr[] = {
'x01', ' ', ' ', ' ', // bytes for num
'r', 'e', 'c', 'v', ' ' // bytes for data
};
MyClass c;
char* ptr = nullptr;
c.read(received_arr);
std::cout << c.num << std::endl;
std::cout << std::string(c.data) << std::endl;
return 0;
}
但是,在MyClass::read
函数中,在读取数字的前 4 个字节后,我的数据指针被重置为 nullptr。
我不知道为什么会这样。模板函数ByteReaderT<int>::read
不应接触数据指针。
在读取 5 字节消息之前,我总是可以为 MyClass::read 中的数据再次分配内存,但这并不干净,因为我不应该这样做。
如果有人看到哪里出了问题,将不胜感激,因为现在我被困住了。
您将std::copy
与std::memcpy
混淆了。
std::copy
是来自<algorithm>
库的算法,它将一对迭代器作为源,一个迭代器作为输出。它将简单地遍历源范围中的每个元素,并在从output
开始的范围内复制它们。
由于您提供了int
作为输出,因此只能编写单个元素。更进一步的是未定义的行为(在您的情况下似乎覆盖了data
成员(。
std::copy
的用法示例:
std::vector<int> a {1, 2, 3, 4, 5};
std::array<int, 5> b;
for(int n: b)
std::cout << n << " "; //0 0 0 0 0
std::copy(a.begin(), a.end(), b.begin());
for(int n: b)
std::cout << n << " "; //1 2 3 4 5
另一方面,std::memcpy
将简单地将内存的内容放在给定的位置并放在另一个地方,这就是您想要实现的目标。
示例用法:
int a = 5;
char[4] b;
std::memcpy(b, &a, 4);