当只使用600 MB内存时,调整QByteArray的大小会抛出std::bad_alloc
Resizing QByteArray throws std::bad_alloc when only using 600 MB of memory
我是Qt的新手,需要加载和处理一些大文件。相反,我的记忆力正在耗尽。以下代码说明了我的问题:
QByteArray mem;
for(int i=1; i<=20; ++i)
{
std::cout << "eating " << (i * 100) << "MB";
mem.resize(i * 100 * 1024 * 1024);
}
当它达到600MB时,我得到了std::bad_alloc。这真的不应该发生。有增加堆大小的秘密开关吗?
我在Windows上使用Qt 5.0.2和Visual C++10.0 x86编译器。
AFAIK QByteArray
分配一个连续的内存块。虽然您的应用程序可能仍有大量可用的虚拟内存,但很有可能由于内存管理器没有足够大的连续内存块,因此分配给阵列的当前内存块无法进一步扩展。
如果你需要处理一些大文件,而不是分配内存并将它们加载到一个块中,我建议你查看内存映射到文件中的"视口"并以这种方式处理它。根据文件的大小,您可能能够将整个文件内存映射到一个块中的内存中。这在Windows上也比逐字节加载文件更高效,因为它利用虚拟内存系统来分页相关文件。
在Windows上,32位进程可以拥有2GB的堆内存。如果此内存不包含足够大的连续块来处理Bytearray,则会遇到错误的分配异常。
MSVC知道/LARGEADDRESSAWARE(处理大地址)和/HEAP(设置堆大小)链接器选项。
您可以检查这些更改是否会影响您可以一次分配的字节数。
在我的x64计算机上,一个在MSVC2012上使用/machine:X86编译的可执行文件为>=1200MB的单个分配抛出了一个错误的分配异常。
如果我将/LARGEADDRESSAWARE
添加到Linker命令行,程序将继续,直到eating 2100MB
之后崩溃。
如果我改为使用/MACHINE:X64进行编译,那么进程会将块分配到8000MB,没有任何异常(可能更多,但我只测试了8GB)。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- C STD ::初始化类对象中的Alloc错误错误