0

I work in Borland C++Builder 6 and have to create a 13230 x 26460 array of double values.

This Matrix size has 350065800 elements and it takes up 350065800 * 8 bytes = 2800526400 bytes = 2.6GB of memory.

I am using 64bit Windows with 8GB RAM.

Even if I set LARGEADDRESSAWARE flag in the image flag option (GF), it cannot declare the array.

Is there any other way to declare a 2.6GB sized array in Borland C++Builder?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Create on the heap. But you'll probably find that 2GB is a hard limit the system wont easily let you exceed. Alternatively, create an array of arrays. – Malcolm McLean Mar 16 '17 at 01:46

2 Answers2

0

You can not have 8 GByte as a single array in BCB6 !!! There are few reasons for this:

  1. You are targeting 32 bit App

    So your OS or emulator can not handle more then 2 or 4 GB of memory. That means 8GB is out of question no matter what you do. And yes even if you have x64 Windows OS your 32 bit app is running in WoW64 emulator ...

  2. Borland allocation new can't allocate single chunk above 1 GB

    Not sure why as the limit should be near 2 or 4 GB but at least for me slightly above the 1GB (even if there is more then 2GB mem free WoW64) is the max limit for safe allocation. Possibly inherited limitation of Borland's memory manager from older versions. This behavior was tested on BDS2006 so not sure if BCB6 is the same but I see no reason why it should not as they share the same memory manager and related C++ engine bugs (which are not present in BCB5 btw).

And finally as you are using new,delete[] you should check this out (just to be sure):

So you need to divide you array into more chunks. As you got 2D matrix so you can use array of arrays as Malcolm McLean suggest. So if cell of you array is T try:

#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;

Just change T (I used double as it is also 8 Byte) for your data type and add checking for new returning NULL

If you really need to have 8GB matrix you need to store it in FILE. Or use 64 bit compiler like RAD2009 or newer.

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • 1
    C++Builder 6 and BDS 2006 **DO NOT** use the same memory manager by default. BDS 2006 was the first version to [switch to FastMM as the default memory manager](https://edn.embarcadero.com/article/33416) (and is still the default manager today), instead of the old BorlandMM memory manager (you can use FastMM in BCB6, though. I do). And Win64 support was not added to C++Builder [until RAD Studio XE3](http://docwiki.embarcadero.com/RADStudio/XE3/en/What%27s_New_in_C%2B%2BBuilder_64-Bit_Windows) (4 releases after RAD Studio 2009). – Remy Lebeau Mar 31 '17 at 21:42
  • @RemyLebeau the question is if they are related as the bugs I got in BDS2006 fixed with adding default constructors... fixes some issues other users got in BCB6 (I do not use it). so either they are related or the bugs are caused by C++ engine and or compiler and only masks as memory conflicts. I do not have enough background knowledge on Borland internals so I can only speculate. – Spektre Apr 01 '17 at 08:22
0

As Remy said, C++ Builder 6 was only capable of creating 32 bit application which was able to consume maximum of 2GB (3GB if you tricked your 32 bit OS) memory. Also normally consuming 8GB of memory is not considered good programming practice.
Having said that, if you absolutely have to do it, you can create a cash memory using CreateFileMapping and MapViewOfFile. This way your data exists on disk, but you can access it like it is in memory. The drawback is, it will be slow.

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);

Don't forget to cleanup using UnmapViewOfFile and CloseHandle. If you don't do it, you might mess up the windows cash memory.

Sam
  • 2,473
  • 3
  • 18
  • 29
  • By the way make sure hFile has enough room to hold all of your data. Before you call CreateFileMapping, you can call [SetFilePointer](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=vs.85).aspx) to grow the file to big enough size to hold all your data. – Sam Apr 04 '17 at 18:02