[comp.sys.mac.programmer] Malloc Summarization.

kevin@crash.cts.com (Kevin Hill) (01/28/91)

  To all who read this.  You may wish to include this posting in a FAQ
file that is posted here regularly..   I have basically come from trying
to use malloc, and discovering every way in how to use it and how to not
use it, and how to get it to do what you want malloc to do, when it doesn't
want to do it!  (Also, I claim that I don't know it all, but I feel that
what I do know now, I have valuable information for those beginning programmers
who are feeling frustrated)
here goes:

The First problem that I encountered, was the I wanted to dynamically allocate
an array of huge proportions. 1.28megs to be exact.
  First, I started with a static variable declared as 
 char		bigmap[12800][100];
of course, my compiler objected.
So I assumed correctly(?) that I could not declare a variable so large, because
it overflows the compiler, and thus, My adventures with malloc!

  First off, to declare a two dimensional variable using malloc, follow these
rules.
  First of all:
declare your variable this way
 char 		**array;
 what this is, is a pointer to a pointer.  Now, we need to decide how large
we want this variable to be and of what type.  For my case I wanted integers so
I declared a pointer to a pointer to point to the memory that I wanted.
 int		**array2;
I could have just used this, (and I did) but for easier and more portable
explanation, I used these two...

Now I need to decide how large I want the array to be.  In my case, it was
100 by 100.

 Now we are into it...  First I need to declare 100 pointers to point to the
areas of memory that will contain the 100 integers each per "level"
                         
so, array = (char **)malloc(100 * sizeof(int *));
now I have an array of 100 pointers to other pointers.  In effect, I am creating
100 pointers to point to the sections in memory of the 100 integers that are in
each segment.   
before I can go on, I need to reserve the memory for 100x100 integers or 10000
integers.
array[0] = (char *)malloc(100*100*sizeof(int);
Now, we need to initialize the pointers to point to the correct 100 per segment
integers.
 so,
 for(x = 1;x < 100;x++)
	array[x] = array[x-1] + 100;
if you follow this with your debugger or look at the FAQ sheet already around,
you will see that this is the same stuff that is there
 
 NOW The good stuff that I found out..

 If you are declaring a memory area greater than 64K or 65535, use calloc. 
and use it in this way:
 what the problem is is that all the memory allocating functions use 
(unsigned) integers as there memory size request format.  if you use a
figure greater than 64k, you will rollover. so 65537 would look like a 1 to
malloc.  This is due to the mac using 2 bytes to store unsigned ints.
To get around this use this little beauty:  find a divisor that will evenly
divide the amount of memory that you are trying to get and use this call:
calloc(divisor,memory amount/divisor)
if you read the calloc description, you will find that this will allocate divisor times memory amount/divisor bytes of memory if it can.
So if you wanted 262144 bytes of memory, and you know that this is too large
to do in one lump sum, but you need contiguous memory, call calloc like this
calloc(8,32768).
this will give you 8 32768byte blocks of contiguous memory if it can.
Sneaky huh?
Anyone with any questions or comments, please write me.
-Kevin
[B
[B[A[B.