c++ - 填充 std::vector 时出现错误分配错误

标签 c++ file-io vector

我正在将三个大型二进制文件(每个大约 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/

相关文章:

c++ - 这个c++代码有什么问题?

c++ - 使用H5Cpp.h头文件编译C++程序

r - 计算每个向量的尾随和前导NA

java - 顺序写入文件与批量写入文件

python - 有进度地递归复制文件

java - 为什么 Vector 和 HashTable 被广泛认为应该被弃用?

c++ - 我无法将 'fill' std::vector 构造函数与 unique_ptrs 一起使用

c++ - 切换枚举类的所有项目时的默认案例编译

c++ - boost::asio 仅在 Visual Studio 中运行时有效

c++ - C++ 中的字符串 : Problems with good() and get()