如何在设置元素中重用向量?
How to re-use vector with set elements?
所以我正在使用我的程序将我的Rasperry Pi相机流式传输到我的计算机上。下面列出的矢量给我带来了问题。在大约 30 秒的流媒体播放后,它让我std::bad_alloc
。有没有办法在循环中一遍又一遍地重用这个向量(例如调整大小,清除)? 以下是简化的代码:
while(isRunning)
{
recv(Connection, received_message, sizeof(received_message), NULL); //receiving the size of image in bytes
fileSize = atoi(received_message);
std::vector<char> fileData(fileSize); //<- this vector is giving me problems
recv(Connection, &fileData[0], CHUNK_SIZE, 0); //Receiving the image
//The code loops over and over again
}
TCP 是一种流协议。它没有消息的概念。在连接的一端写入 10,000 字节并不意味着所有 10,000 字节都将到达接收器并同时可用。
因此,recv
与现有的东西一起工作。它返回当前可用的任何内容,如果没有可用,recv
等待数据可用。这意味着,如果您要求 10,000 字节,您可能会完全根据网络堆栈的心血来潮获得 1 字节到 10,000 字节之间的任何字节,一个 IP 数据包中可以传输的最大数据量,以及太多其他变量无法列出。
所以
recv(Connection, received_message, sizeof(received_message), NULL);
可能会在收到所有received_message
之前返回。fileSize
将从错误的输入中计算,很可能是一个不以 null 结尾的字符串,并且在缓冲区末尾运行,触发未定义的行为,垃圾输入会发出垃圾。
然后,此不正确的fileSize
用于调整vector
的大小,现在几乎可以肯定是错误的大小。如果太小,
recv(Connection, &fileData[0], CHUNK_SIZE, 0);
可能会在vector
结束时流出更多未定义的行为。如果存储太大,系统可能无法为vector
分配存储,因为没有足够的连续存储可用。这似乎是OP发生的事情。
解决方案:循环所有调用recv
,直到到达所需的数据量,然后再继续。写入备用路径以处理已关闭或失败的连接。所有调用必须读取正确的数据量或
recv(Connection, &fileData[0], CHUNK_SIZE, 0);
可以提前退出离开下一个
recv(Connection, received_message, sizeof(received_message), NULL);
将图像的一部分读取为received_message
,导致fileSize
像received_message
没有完全填充一样疯狂。
此外,请考虑在recv
上设置超时,以便在您希望终止程序时有机会读取退出标志。否则,它可能会永远阻止永远不会到达的数据。
您可以像这样轻松重用std::vector
:
std::vector<char> fileData;
while(isRunning)
{
ssize_t n = recv(Connection, received_message, sizeof(received_message), 0); //receiving the size of image in bytes
if (n < 0)
throw std::runtime_error(std::string("Connection error (getting fileSize)") + strerror(errno));
assert(n == sizeof(received_message));
fileSize = atoi(received_message);
if (fileSize > maxFileSize or fileSize == 0)
throw std::runtime_error("Invalid fileSize " + std::to_string(fileSize));
fileData.resize(fileSize);
size_t received = 0;
while (received < fileSize)
{
ssize_t n = recv(Connection, fileData.data() + received, fileSize - received, 0); //Receiving the image
if (n < 0)
throw std::runtime_error(std::string("Connection error (getting image)") + strerror(errno));
received += n;
}
//The code loops over and over again
}
一些注意事项:
- 处理第一个
recv
未收到sizeof(received_message)
字节的事件(当前受assert
保护) - 您应该定义
maxFileSize
- 包括
<cassert>
、<exception>
和<string>
标题 - 使用
-std=c++11
进行编译
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 在 C++ 中输出枚举类类型的向量元素
- 用向量的向量元素初始化向量的空向量
- 为什么不允许使用可变长度数组作为向量元素?
- 在函数中传递向量元素
- 使用 Rcpp 加速替换迭代算法中的列表和向量元素是否合法?
- 返回向量元素的 l 值的正确方法是什么?
- 当向量增长时,指向向量元素的C++指针是否无效
- 如何在C++中从一个向量元素减去std::unorderede_map向量元素并更新它
- C++:向量元素赋值导致访问冲突
- 将向量元素与字符串元素进行比较,而不初始化向量
- 从2D矢量中找出最小尺寸的向量元素的更好方法
- 当我尝试将一个向量元素的值分配给另一个向量元素时,为什么我的应用程序会崩溃
- 使用递归C++向量元素的总和
- 如何查找为数组中的最低值编制索引的向量元素
- 限制指针访问STL ::向量元素
- 访问索引指向向量元素时的seg故障 - 做错了什么
- 如何使用指针访问向量元素的各个元素
- 向量元素数据损坏了Find()操作
- 将字符值分配给向量元素.C