From: colin@cole.research.canon.oz.au (Colin Pickup)
Subject: Re: Using 64k objects
Organization: Canon Information Systems Research Australia
Date: Tue, 10 Nov 1992 00:15:05 GMT

In article <1992Nov4.011604.5884@piccolo.cit.cornell.edu>  
sl14@crux3.cit.cornell.edu (Stephen Lee) writes:
> I'm writing a program which allocates a large array of unsigned int.
> I'm passing the array to a function which then manipulates it.  No
> problem until I tried a large number (32768):  The function seems to
> be overwriting its variables.  I can use an array of 16384 elements
> and get the correct result.
> 
> So, is there any restrictions using large arrays on a PC?  The problem
> seems to be caused by the array crossing a segment boundry:  32768
> ints are 64k in size.
> 
> The compiler I'm using is BC++ 2.0, and I tried compiling with
> align byte or align word, stack checking on/off, and large/small
> memory model.  In small model it overwrites its variables.  In large
> model it doesn't, but it screws up memory and 4DOS barfs about error
> allocating memory when the program exits.
> 
> The program is as follows:
> 
> Note:  word is typedef'd as unsigned int.
> 	The function is fft_idx, which stops in the middle of the 
> 	#ifdef DEBUG block, at i = 14202 (or near that) 
> 
> // fft.cpp: Fast Fourier Transform
> 
> #include <stdlib.h>
> #include <math.h>
> #include <complex.h>
> #include "auxtypes.h"
> 
> // pointer equiv. of 0, a.k.a. NULL
> #define NIL 0
> 
> #define DEBUG
> 
> #ifdef DEBUG
> #include <iostream.h>
> #include <iomanip.h>
> #endif
> 
> #define _2_PI 6.28318530717958647692528676655900576839433879875016
> complex _neg_2_pi_i = complex(0, -_2_PI);
> 
> void fft_idx(word nmax, word *idx)
> /*
>  * Calculate index for the elements in the final butterfly arrangement.
>  */
> {
>   word i, n2;
>   unsigned long n;  // screw up in the for loop if word is used:
>                     // becomes 0 after rolling off 32768, n <= nmax  
always
> 
>   idx[0] = 0;
>   for (n = 2L; n <= nmax; n <<= 1) {
>     n2 = (word) n>>1;
>     for (i = 0; i < n2; i++) {
>       idx[i] <<= 1;
>       idx[i+n2] = idx[i] + 1;
> #ifdef DEBUG
>       if (n2 == 16384 && n != 32768L) {
>         cout <<"n : "<<n<<"\ni: "<<i<<"\nn2: "<<n2<<"\n";
>         exit(1);
>       }
> #endif
>     }
> #ifdef DEBUG
>     cout << n << ", " << n2 << endl;
> #endif
>   }
> }
> 
> complex *fft(word n, complex *&in, complex *&out)
> /*
>  * Do a FFT on the complex array 'in' of size 'n'
>  * Returns the address of 'out'
>  * The array 'in' is scrambled, and pointer 'in' may also swap with  
'out'
>  *
>  * 'n' is expected to be a power of 2, and no bigger than 32768
>  * (or whatever power of 2 an unsigned int can hold)
>  */
> {
>   word *idx;
>   word i;
> 
>   if ((idx = new word[n]) == NIL)
>     return NIL;
>   fft_idx(n, idx);
> #ifdef DEBUG
>   for (i = 0; i < n; i++)
>     cout << setw(7) << idx[i] << ",";
>   cout << endl;
> #endif
> }
> 
> #ifdef DEBUG
> void main()
> {
>   complex *in, *out;
>   word n;
> 
>   cerr << "n?\n";
>   cin >> n;
> 
>   fft(n, in, out);
> }
> #endif
> --
> Stephen Lee
> Internet: sl14@crux2.cit.cornell.edu

Borland is one of the few C/C++ compilers that handles arrays bigger that  
64K. To do it either use the huge memory model for the whole program or  
just make the pointers to the arrays huge (read the manuals on how to do  
this). The second option will give better run-time performance.

NOTE : you can not use new to allocate arrays bigger than 64K. The size  
parameter for new is a unsigned, i.e. 16 bits. You must use hugealloc and  
hugefree (again look in the manual for these functions).
Colin Pickup

Newsgroups: comp.lang.c++