在C ++ Builder中分配大型数组

时间:2017-03-16 01:42:52

标签: c++builder c++builder-6

我在Borland C ++ Builder 6中工作,必须创建一个double值的13230 x 26460数组。

此矩阵大小包含350065800个元素,占用内存350065800 * 8 bytes = 2800526400 bytes = 2.6GB

我正在使用带有8GB RAM的64位Windows。

即使我在图像标志选项(GF)中设置LARGEADDRESSAWARE标志,它也不能声明数组。

还有其他方法可以在Borland C ++ Builder中声明2.6GB大小的数组吗?

2 个答案:

答案 0 :(得分:0)

BCB6 中,您不能将 8 GByte 作为单个数组!原因很简单:

  1. 您的定位是32位应用

    因此,您的操作系统或模拟器无法处理超过2或4 GB的内存。这意味着无论你做什么,8GB都是不可能的。是的,即使你有x64 Windows操作系统,你的32位应用程序也在WoW64模拟器中运行......

  2. Borland分配new无法分配超过1 GB的单个块

    不确定为什么限制应该接近2或4 GB,但至少对我来说略高于 1GB (即使有超过2GB的无内存WoW64)是安全的最大限制分配。可能从旧版本继承了Borland内存管理器的限制。此行为已在 BDS2006 上进行了测试,因此不确定 BCB6 是否相同,但我认为没有理由不这样做,因为它们共享相同的内存管理器和相关的 C ++ 引擎错误( BCB5 btw中不存在)。

  3. 最后当你使用new,delete[]时,你应该检查一下(只是为了确定):

    因此,您需要将阵列分成更多块。当您获得2D矩阵时,您可以使用 Malcolm McLean 建议的阵列数组。因此,如果您的数组的单元格为T,请尝试:

    #define T double
    T **m=new T*[13230];
    for (int i=0;i<13230;i++) m[i]=new T[26460];
    
    m[10000][20000]=1.2345; // do your stuff with m[][]
    
    for (int i=0;i<13230;i++) delete[] m[i];
    delete[] m;
    

    只需为您的数据类型更改T(我使用double,因为它也是8字节),并添加new返回NULL的检查

    如果你真的需要8GB矩阵,你需要将它存储在FILE中。或者使用64位编译器,如 RAD2009 或更新。

答案 1 :(得分:0)

正如Remy所说,C ++ Builder 6只能创建32位应用程序,它能够消耗最大2GB(如果你欺骗了32位操作系统,则为3GB)内存。通常消耗8GB的内存也不被认为是良好的编程习惯。
话虽如此,如果你必须这样做,你可以使用CreateFileMappingMapViewOfFile创建一个现金存储器。这样您的数据就存在于磁盘上,但您可以像在内存中一样访问它。缺点是,它会很慢。

HANDLE hFile = ::CreateFile(fileName, ...);
HANDLE hFM = ::CreateFileMapping(hFile, ...);
double**m= (double**)::MapViewOfFile(hFM, ...);
m[10000][20000]=1.2345; // do your stuff with m[][]
::UnmapViewOfFile((void*)m); 
::CloseHandle(hFM);
::CloseHandle(hFile);

不要忘记使用UnmapViewOfFileCloseHandle进行清理。如果你不这样做,你可能会弄乱Windows现金存储器。