如何使用set元素重用vector?

时间:2017-01-20 06:44:59

标签: c++ linux windows vector raspberry-pi

所以我正在使用我的程序将我的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
}

2 个答案:

答案 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>
  • 进行编译