仅使用600 MB内存时,调整QByteArray的大小会抛出std :: bad_alloc

时间:2013-06-21 23:18:34

标签: c++ windows qt

我是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和Visual C ++ 10.0 x86编译器上使用Qt 5.0.2。

2 个答案:

答案 0 :(得分:5)

AFAIK QByteArray分配连续的内存块。虽然您的应用程序可能仍有大量可用的虚拟内存,但是您的阵列所分配的当前内存块很可能无法进一步扩展,因为您的内存管理器没有足够大的连续块。

如果你需要处理一些大文件,而不是分配内存并将它们加载到一个块的内存中,我建议查看内存将“视口”映射到文件中并以这种方式处理它。根据文件的大小,您可能能够将整个文件的内存映射到一个块中的内存中。这在Windows上比在逐字节加载文件时效率更高,因为它利用虚拟内存系统在相关文件中进行分页。

答案 1 :(得分:2)

在Windows上,32位进程可以拥有2 GB的堆内存。如果此内存不包含足以处理Bytearray的连续块,则会遇到错误的分配异常。

MSVC知道/LARGEADDRESSAWARE (Handle Large Addresses)/HEAP (Set Heap Size)链接器选项。

您可以检查对这些更改是否会影响您可能一次分配的字节数。

在我的x64机器上,在MSVC2012上使用/ MACHINE:X86编译的可执行文件会为单次分配&gt; = 1200MB引发错误的alloc异常。

如果我将/LARGEADDRESSAWARE添加到链接器命令行,程序将继续运行,直到它在eating 2100MB之后崩溃。

如果我使用/ MACHINE:X64编译,则进程会将块分配给8000MB而没有任何异常(可能更多,但我只测试直到8GB)。