[comp.sys.mac.programmer] "Large" arrays in Think C

kwhyte@arthur.uchicago.edu (Kevin Whyte) (11/30/90)

   This must be a simple thing to do:  I'm running on a Mac ][
with 5 M, but Think C won't let me use arrays larger than about
64K!  What am I missing.  I tried the "partition size" under 
Set Project Type, and it started giving me out of memory errors.
I even gave Think C about 3M to play with, but it didn't help.
Thanks in advance for any advice.

-Kevin Whyte (Kwhyte@math.uchicago.edu)

rg2c+@andrew.cmu.edu (Robert Nelson Gasch) (11/30/90)

>   This must be a simple thing to do:  I'm running on a Mac ][
>with 5 M, but Think C won't let me use arrays larger than about
>64K!  What am I missing.  I tried the "partition size" under 

Due to the architecture of the 680xx processors, the size limit
for a single data or code unit is 32K. If you need data bigger
than that, you have to allocate it dynamically. The problem here
is that you have to limit the number of pointers you allocate,
otherwise the momory manager will get *really* slow.

If you have further questions, feel free to write back.
--> rob

gillies@m.cs.uiuc.edu (12/02/90)

The THINK C compiler could do a better job of documenting this
bug/feature.  Why can't THINK C's error message read like this:

	Error:  Arrays larger than 32K must be allocated from the heap
		see pXYZ, Think C manual.


This is my "wish" for THINK C.  We're beginning to get this question
as often as the "What does a flashing apple mean?" question!!!!!!!!!

oster@well.sf.ca.us (David Phillip Oster) (12/03/90)

In article <1990Nov29.213603.12527@midway.uchicago.edu> kwhyte@arthur.uchicago.edu (Kevin Whyte) writes:
>   This must be a simple thing to do:  I'm running on a Mac ][
>with 5 M, but Think C won't let me use arrays larger than about 64K!

I am surprised you are seeing problems at 64k. THINK C complains if you try
to allocate more than 32k of static data. The solution is to allocate it
dynamically. 

For a one dimensional array that was originally:

float floats1[1000];

change this declaration to:

float *floats1;	/* 1000 */

and put at the start of your program:

	floats1 = (float *) NewPtr(1000L * sizeof(float));

for a multidimnsional array that was originally:

float	floats3[10][9][8];

change this declaration to:

typedef float FloatsRow[9][8];
FloatsRow	**floats3;	/* 10 */
#define sizeof_floats3	(10L*sizeof(FloatsRow))

and put at the start of your program:

	floats3 = (FloatsRow **) NewPtr(sizeof_floats3);
	for(i = 0;i < 10;i++){
		floats3[i] = (FloatsRow *) NewPtr(sizeof(FloatsRow));
	}

in both cases, after this initial setup, the remainder of the program is 
unchanged. (provided that the remainder of the program has been recompiled
with the new declarations of floats1 and floats3. You can get them initialized
to zero by using NewClearPtr() instead of NewPtr(). If NewClearPtr is not
defined in your version, it is:

#include <asm.h>
Ptr NewClearPtr(size)long size;{
	asm{
		move.l	size,d0
		_NewPtr	CLEAR
		move.l	a0, d0
	}
}

In a real program, make sure that you declare:
Ptr NewPtr(long);
before you use it (and the same with NewClearPtr()). Make sure you check the
value returned by NewPtr and if it NIL (i.e., NULL, or 0L). put up an error
alert and quit.
-- 
-- David Phillip Oster - At least the government doesn't make death worse.
-- oster@well.sf.ca.us = {backbone}!well!oster

phils@chaos.cs.brandeis.edu (Phil Shapiro) (12/03/90)

I know this is really nitpicking, but it can save you typing in the
NewClearPtr() glue.  The naming scheme for the new Memory Manager
calls follow the way they're called in assembly.  The 'new' functions
(TN #219) are:

NewPtrClear(), NewPtrSys(), NewPtrSysClear()
NewHandleClear(), NewHandleSys(), NewHandleSysClear()

Think C and Pascal (and MPW, of course) all know about these
functions.

	-phil
--
   Phil Shapiro                           Technical Support Analyst
   Language Products Group                     Symantec Corporation
		Internet: phils@chaos.cs.brandeis.edu