2013-06-21 56 views
3

我是Qt的新手,需要加載和處理一些大文件。相反,我的內存不足。下面的代碼說明了我的問題:當僅使用600 MB內存時調整QByteArray的大小會拋出std :: bad_alloc

QByteArray mem; 
for(int i=1; i<=20; ++i) 
{ 
    std::cout << "eating " << (i * 100) << "MB"; 
    mem.resize(i * 100 * 1024 * 1024); 
} 

我得到std :: bad_alloc達到600MB時。這真的不應該發生。 是否有一個祕密開關來增加堆大小?

我在Windows和Visual C++ 10.0 x86編譯器上使用Qt 5.0.2。

回答

2

在Windows上,32位進程可以擁有2 GB的堆內存。如果這個內存不包含足夠大的連續塊來處理你的Bytearray,你將會遇到一個錯誤的分配異常。

MSVC知道/LARGEADDRESSAWARE (Handle Large Addresses)/HEAP (Set Heap Size)鏈接器選項。

您可以檢查是否有任何更改會影響您可以一次分配的字節數。

在我的x64機器上,使用MSVC2012上的/ MACHINE:X86進行編譯的可執行文件在單個分配> = 1200MB時拋出了錯誤的alloc異常。

如果我將/LARGEADDRESSAWARE添加到Linker命令行,程序將繼續執行,直到在eating 2100MB之後崩潰。

如果我使用/ MACHINE:X64進行編譯,進程將塊分配給8000MB,沒有任何異常(甚至更多,但是我只測試了8GB)。

+0

很好的答案。我不知道/ LARGEADDRESSAWARE選項。 – MadDave

+0

不過,我很驚訝,我遇到了相對較小的分配問題。從500MB調整到600MB意味着我在內存中有一個500MB的塊,需要一個600MB的塊。聲音在2GB堆中可用。碎片不會那麼糟......但我想你一定是對的。無論如何,沒有理由爲什麼我不應該使用x64。 – MadDave

+0

我沒有看過QByteArray的實現,但是如果它在內存塊的原地擴展,即使最小的碎片可能會導致問題。 –

5

AFAIK QByteArray分配連續的內存塊。雖然您的應用程序可能仍有大量虛擬內存可用,但由於您的內存管理器沒有足夠大的連續塊,因此很有可能您的陣列所分配的當前內存塊不能再擴展。

如果您需要處理一些大文件,而不是分配內存並將其加載到內存中,我建議您查看將視口映射到文件並以此方式處理的內存。根據文件的大小,你可能很可能將整個文件映射到一塊內存中。在Windows上這比在文件中逐字節地加載文件更有效,因爲它利用虛擬內存系統在相關文件中進行分頁。

+0

+1基本上是正確的,但我使用的庫需要內存中的整個文件。我主要感興趣的是爲什麼分配失敗: – MadDave

+1

您是否需要特定數據結構中的內存文件,或者是否需要一個指向文件開頭和文件結尾的指針,它們都指向「內存」地點?巨大差距。 –

相關問題