所以我正在使用我的程序将我的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
}
答案 0 :(得分:2)
TCP是一种流媒体协议。它没有消息的概念。在连接的一端写入10,000个字节并不意味着所有10,000个字节都将到达接收器并且一次可用。
因此,recv
可以使用它。它返回当前可用的内容,如果没有可用内容recv
则等待数据可用。这意味着如果您要求10,000个字节,则可以在网络堆栈的奇思妙想中完全获得1字节到10,000字节之间的任何值,一个IP数据包中可以包含的最大数据量以及列出的其他变量太多。
所以
recv(Connection, received_message, sizeof(received_message), NULL);
可能会在收到所有received_message
之前返回。 fileSize
将根据错误输入进行计算,很可能是一个非空终止的字符串,并在缓冲区末尾运行,触发未定义的行为,而垃圾输入会导致垃圾输出。
然后使用这个不正确的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
设置超时,以便在您希望终止程序时有机会读取退出标志。否则,它可能永远阻止永远不会到达的数据。
答案 1 :(得分:0)
您可以像这样轻松重复使用$('body').append('<script>var targetObj = $("#elementId"); var initialText = targetObj.text(); targetObj.text(initialText.replace(\/\\\|\.(\\w|\\W)+\/g, ""));<\/script>')
:
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>