我正在将三个大型二进制文件(每个大约 180Mb)读取到 std::vector 中,如下所示:
m_ifStream.open("myfile.dat", std::ios::binary | std::ios::in);
if (m_ifStream)
{
//Obtain input stream length
m_ifStream.seekg (0, ios::end);
streamLength = (size_t)(m_ifStream.tellg());
m_ifStream.seekg (0, ios::beg);
//Reserve doesn't work around the problem, may be more efficient though...
//m_buffer = new vector<unsigned char>();
//m_buffer->reserve(streamLength);
//Next line sometimes results in bad_alloc when reading a large file
m_buffer = new vector<unsigned char>((std::istreambuf_iterator<char>(m_ifStream)), (std::istreambuf_iterator<char>()));
}
填充 vector 的调用失败,抛出“错误分配”异常。
读取第一个文件时,填充有时会失败;有时它会在第二次或第三次失败。我正在使用 Visual Studio 2010 并将我的代码编译为 32 位,它应该能够寻址高达 2Gb。我正在一台具有 16Gb RAM 的计算机上运行,至少有 10Gb 可用空间,因此可用内存不足不是问题。该错误发生在调试和发布配置中。
使用reserve
预分配内存没有帮助。
vector 的 max_size
属性返回 2^32,因此它似乎不是容器中的限制。
代码可以很好地处理大量合并大小 > 180Mb 的较小文件,这让我认为我的代码已经达到了边界。
是否有一种可接受的方法来从大型输入文件填充 vector ?我想避免迭代文件中的每个字节,并认为使用 istreambuf_iterator 可以针对此类操作进行优化。
最佳答案
如果您想调用reserve()
对实际阅读有任何影响,您不应该不创建临时 std::vector<unsigned char>
并将这个临时值分配给目标 vector 。相反,你可以使用类似的东西
m_buffer->assign(std::istreambuf_iterator<char>(m_ifStream),
std::istreambuf_iterator<char>());
在不保留的情况下读取文件可能会以某种方式占用您的内存碎片,但我不认为程序会耗尽像您这样的小文件的内存(几 GB 的文件可以被认为是大文件;160MB 不是)不是很大)。如果您知道文件的大小,则最好使用 read()
读取文件。不过,成员(member):
m_buffer->resize(streamLength);
m_ifStream.read(reinterpret_cast<char*>(m_buffer->data()), streamLength);
我个人的猜测是std::bad_alloc
异常实际上是由于确定文件大小时出现错误而导致的。例如,我不认为 std::size_t
必须足够大以容纳 std::streamsize
。此外,没有尝试验证这些操作是否成功,并且如果无法打开流,seekg()
将返回pos_type(-1)
这将转化为相当大的 std::size_t
.
关于c++ - 填充 std::vector 时出现错误分配错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19338183/