在我的应用程序中,我保存了体素数据(压缩字节数组)并尝试将其重新加载到内存中。
但我的应用程序在Windows 7计算机(64位,12 GB)中崩溃,给出了bad_alloc。
这在Linux上运行良好,甚至可以在其他具有4 GB内存的Windows 7机器上运行。
压缩的大小约为200Mb,未压缩的字节大小约为300Mb(因此在此'new'语句之前仅保留500 MB,这使得除系统内存之外几乎留下8 GB)。在此之前我没有运行任何其他主要的内存分配步骤,所以我不认为内存是碎片化的。
我使用MinGW GCC
版本4.5.0
有关此的任何提示吗?
提前感谢。
QFile fileVol(strVFile);
//Read VolumeData
fileVol.open(QIODevice::ReadOnly);
QDataStream volstream(&fileVol);
QByteArray volCmprsdByteArray; //This holds the compressed byte array
//Read some additional information
int nx, ny, nz, bbp;
int voltype;
volstream >> nx;
volstream >> ny;
volstream >> nz;
volstream >> bbp;
volstream >> voltype;
volstream >> volCmprsdByteArray; //read our compressed voxel-data
//we have original uncompressed pixel data
QByteArray volUncmprsdByeArray = qUncompress(volCmprsdByteArray);
int uncompressedSize = volUncmprsdByeArray.size(); // size of the byte array
qDebug("new char for uncompressed data size %d",uncompressedSize);
unsigned char* volumeData=NULL;
//Trying to allocate new memory
try {
// ##### breaks here. ####
volumeData =new unsigned char[uncompressedSize];
}
catch (std::bad_alloc e)
{
cout << "lu_solver() bad_alloc: " << e.what() << endl;
cout << "Size " << uncompressedSize << endl;
//return;
}
答案 0 :(得分:3)
如果您在Windows上将程序构建为32位二进制文件,则只能获得2GB的可用地址空间(上半部分是保留的)。
如果你认为地址空间可以通过分配大量不同的东西(DLL加载,线程堆栈,动态分配)来分段,那么很可能你最终会很快失败。
您可以尝试为链接器提供/LARGEADDRESSAWARE
标志,这将在正确配置的32位Windows上为您提供3GB的地址空间,在64位Windows上提供完整的4GB地址空间。但是,真的,找到重新实现程序的方法是个好主意,这样你就可以使用几个较小的分配而不是一个较大的分配。
答案 1 :(得分:1)
对于非常大的分配,您可能会遇到碎片问题:例如,堆可能有600mb的内存,但是切换为100mb的块,因此您无法分配单个500mb块。 new
(在大多数情况下真正调用malloc()
)的某些实现对于发生这种情况时优雅地失败并不是很明智。
通过如此大的分配,您可以在Windows上使用特定于操作系统的功能,例如VirtualAlloc()和HeapAlloc()。
答案 2 :(得分:0)
如果您的数据大小是固定的,或具有已知的上限,您可以尝试在堆栈或全局变量中进行静态分配。