【问题标题】:Bad alloc error when creating a 4GB std::string创建 4GB std::string 时出现错误分配错误
【发布时间】:2020-11-24 08:10:53
【问题描述】:

我正在使用多解析器发送 http POST 请求,我需要发送一个大文件 (4Go)。 但是,当我测试我的代码时,它给了我一个 bad_alloc 异常并崩溃。我尝试使用较小的文件,它适用于小于 500Mo 的文件,但文件越大,它随机崩溃的次数就越多。 你能帮帮我吗?

这是发生崩溃的代码。它是在构建请求正文时:

std::ifstream ifile(file.second, std::ios::binary | std::ios::ate); //the file I am trying to send
std::streamsize size = ifile.tellg();
ifile.seekg(0, std::ios::beg);
char *buff = new char[size];
ifile.read(buff, size);
ifile.close();
std::string ret(buff, size); //this make the bad_alloc exception
delete[] buff;
return ret; //return the body of the file in a string

谢谢

【问题讨论】:

  • 您可能想要打印 size 的值并捕获“new”在内存不足时可能抛出的异常。
  • 哦,顺便说一句,std::streamsize 是一个有符号的 int,根据:stackoverflow.com/questions/24482028/…。这可以解释为什么大于 2GB 的值会造成问题......
  • 你应该发送 4 GB 的小块......
  • 真正的问题是您首先尝试将 4GB 文件读入内存。看看你的“multiparser”库(不管是什么)是否不能被说服从文件句柄或回调中读取请求的主体(就像 curl 那样)。如果它绝对必须有一个指向内存的指针,请使用mmapMapViewOfFile 以有效的方式将文件映射到您的内存中。
  • 另外你不应该两次分配数据,buff ret

标签: c++ bad-alloc


【解决方案1】:

std::string ret(buff, size); 创建buff 的副本。所以你基本上是内存消耗的两倍

https://www.cplusplus.com/reference/string/string/string/

(5) 来自缓冲区

从 s 指向的字符数组中复制前 n 个字符。

那么问题就变成了您实际拥有多少,分别是您的操作系统允许您获得多少(例如,Linux 上的ulimit

正如 cmets 所说,您应该分块读取并使用多个 POST 请求发送单个块。

您可以遍历ifstream 检查是否达到ifile.eof() 作为循环的退出条件:

std::streamsize size = 10*1024*1024 // read max 10MB
while (!ifile.eof())
{
    std::streamsize readBytes = ifile.readsome(buff, size);
    // do your sending of buff here.
}

您需要考虑错误处理,例如不要泄漏buff 或让ifile 保持打开状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 2014-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多