如何获取std::vector<int>*的值?vector序列化传输后接收异常如何解决
问题根因
你当前的错误核心是直接序列化了std::vector对象本身,忽略了std::vector的存储逻辑:std::vector作为容器,自身只存储指向堆内存的元素指针、当前长度、容量三个元信息,实际的元素数据都存在堆内存中,你只拷贝vector对象本身,相当于只传了一个原进程有效的内存地址,跨进程/网络传输后这个地址完全无效,自然拿不到真实数据。
另外你客户端直接将读到的内存强转为std::vector<int>*属于野指针访问,必然会出异常,本次运行输出空地址只是崩溃前的偶然结果。
正确实现方案
网络传输非POD类型必须手动序列化实际负载数据,不能直接拷贝容器对象本身,步骤如下:
服务端序列化逻辑
- 写入包类型
type - 写入vector的元素个数
size(用于客户端确定需要读取的元素数量) - 写入
vector.data()指向的实际元素数组,长度为size * sizeof(元素类型)
客户端反序列化逻辑
- 读取包类型
type2 - 读取元素个数
size2,调用vec2.resize(size2)为元素分配空间 - 将buffer中对应长度的元素数据拷贝到
vec2.data()指向的地址
修正后的可运行代码
#include <vector> #include <iostream> #include <cstring> int main() { /* -- server -- */ // variables to buffer std::vector<int> vec = { 1, 25, 156, 0, 1 }; short type = 25; int written = 0; char buffer[256] = {}; // 1. 写入包类型 memcpy(&buffer[written], &type, sizeof(type)); written += sizeof(type); // 2. 写入vector元素个数 size_t vec_size = vec.size(); memcpy(&buffer[written], &vec_size, sizeof(vec_size)); written += sizeof(vec_size); // 3. 写入vector实际元素数据 memcpy(&buffer[written], vec.data(), vec_size * sizeof(int)); written += vec_size * sizeof(int); std::cout << "/* -- Server -- */\n" << std::endl; std::cout << "[written] --> " << "Size : " << sizeof(written) << " | Value : " << written << std::endl; std::cout << "[type] --> " << "Size : " << sizeof(type) << " | Value : " << type << std::endl; std::cout << "[vec] --> " << "Element Count : " << vec.size() << " | First Element Value : " << vec[0] << std::endl; // 模拟发送接收 char buffer2[256] = {}; memcpy(&buffer2, &buffer[0], sizeof(buffer2)); /* -- client -- */ // buffer to variables std::vector<int> vec2; short type2 = 0; int read = 0; // 1. 读取包类型 memcpy(&type2, &buffer2[read], sizeof(type2)); read += sizeof(type2); // 2. 读取元素个数,分配空间 size_t vec2_size = 0; memcpy(&vec2_size, &buffer2[read], sizeof(vec2_size)); read += sizeof(vec2_size); vec2.resize(vec2_size); // 3. 读取实际元素数据 memcpy(vec2.data(), &buffer2[read], vec2_size * sizeof(int)); read += vec2_size * sizeof(int); std::cout << "\n\n"; std::cout << "/* -- Client -- */\n" << std::endl; std::cout << "[read] --> " << "Size : " << sizeof(read) << " | Value : " << read << std::endl; std::cout << "[type2] --> " << "Size : " << sizeof(type2) << " | Value : " << type2 << std::endl; std::cout << "[vec2] --> " << "Element Count : " << vec2.size() << " | Elements : "; for (auto num : vec2) { std::cout << num << " "; } std::cout << std::endl; std::cout << "\n"; system("pause"); return 0; }
运行结果示例
/* -- Server -- */ [written] --> Size : 4 | Value : 30 [type] --> Size : 2 | Value : 25 [vec] --> Element Count : 5 | First Element Value : 1 /* -- Client -- */ [read] --> Size : 4 | Value : 30 [type2] --> Size : 2 | Value : 25 [vec2] --> Element Count : 5 | Elements : 1 25 156 0 1 Press any key to continue. . .
内容的提问来源于stack exchange,提问作者The_ChaosStar
相关产品推荐
相关产品推荐

