home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume2 / runtime < prev    next >
Internet Message Format  |  1986-11-30  |  23KB

  1. From: decvax!allegra!phri!roy (Roy Smith)
  2. Subject: run-time memory allocation for multi-dimensional arrays
  3. Newsgroups: mod.sources
  4. Approved: john@genrad.UUCP
  5.  
  6. Mod.sources:  Volume 2, Issue 36
  7. Submitted by: decvax!allegra!phri!roy (Roy Smith
  8.  
  9.     A while ago, there was a discussion (in net.unix-wizards?) about
  10. how to get dynamic memory allocation (using malloc() and friends).  If I
  11. remember correctly the answer was that you couldn't, for an assortment of
  12. reasons.  Well, I didn't follow those discussions too closely because they
  13. didn't seem interesting at the time.
  14.  
  15.     However, I recently ran accross a need for just such a thing so I
  16. sat down and wrote what I think is a nifty solution to the problem which
  17. goes back to the old Fortran days -- vectored arrays.  It turns out it
  18. isn't hard at all (the documentation is several times longer than the code,
  19. which perhaps is the way it should be with everything), and as far as I can
  20. tell, is portable.
  21.  
  22.     I apologize to those of you Sys5 types who don't have the -me
  23. macros to properly print out the documentation.  The man page uses the
  24. regular -man macros, so that should work.  As for the accompanying paper,
  25. do the best you can.  I suppose I could have submitted the already
  26. formatted version, but that seemed rather tacky.  If enough people ask,
  27. however, I'll do so when I post the (inevitable) bug fixes.
  28.  
  29. [ moderator's note:  I added the a formatted copy of the paper to
  30.   the distribution to avoid the problem  - John Nelson, moderator ]
  31.  
  32.     Anyway, here it is.  Just read this into your favorite editor, cut
  33. on the dotted line and ... Oh hell, you know what to do.  Have fun, write
  34. if you get the chance, and remember to say hello to everybody for me.
  35.  
  36. Roy Smith <allegra!phri!roy>
  37. System Administrator, Public Health Research Institute
  38. 455 First Avenue, New York, NY 10016
  39.  
  40. ---------there be monsters below this line-----------
  41.  
  42. #! /bin/sh
  43. # This is a shell archive, meaning:
  44. # 1. Remove everything above the #! /bin/sh line.
  45. # 2. Save the resulting text in a file.
  46. # 3. Execute the file with /bin/sh (not csh) to create the files:
  47. #    Makefile
  48. #    Read_me
  49. #    arrayalloc.3
  50. #    arrayalloc.c
  51. #    arrayalloc.me
  52. #    arrayalloc.txt
  53. #    test.c
  54. # This archive created: Tue Aug 13 07:55:16 1985
  55. export PATH; PATH=/bin:$PATH
  56. echo shar: extracting "'Makefile'" '(675 characters)'
  57. if test -f 'Makefile'
  58. then
  59.     echo shar: will not over-write existing file "'Makefile'"
  60. else
  61. sed 's/^X//' << \SHAR_EOF > 'Makefile'
  62. #
  63. # Makefile for array allocation routines
  64. # $Header: Makefile,v 1.3 85/08/12 17:27:17 roy Rel $
  65. #
  66. # $Log:    Makefile,v $
  67. # Revision 1.3  85/08/12  17:27:17  roy
  68. # Added "Makefile" to ${FILES}.
  69. # Revision 1.2  85/08/12  17:07:40  roy
  70. # Fixed "make shar"
  71. # Revision 1.1  85/08/12  16:56:48  roy
  72. # Initial revision
  73. #
  74.  
  75. XSRCS =    test.c arrayalloc.c
  76. DOCS =    arrayalloc.me arrayalloc.3 Read_me
  77. XFILES =    ${SRCS} ${DOCS} Makefile
  78.  
  79. CFLAGS = -g
  80.  
  81. test:        test.o arrayalloc.o
  82.         cc -o test test.o arrayalloc.o
  83.  
  84. shar:        ${FILES}
  85.         shar -c -v ${FILES} > arrayalloc.shar
  86.  
  87. lint:        ${SRCS}
  88.         lint ${SRCS}
  89.  
  90. clean:        .
  91.         rm core *.o test *~*
  92.  
  93. rcs:        RCS
  94.         for file in ${FILES}; do co $$file; done
  95. SHAR_EOF
  96. if test 675 -ne "`wc -c < 'Makefile'`"
  97. then
  98.     echo shar: error transmitting "'Makefile'" '(should have been 675 characters)'
  99. fi
  100. fi # end of overwriting check
  101. echo shar: extracting "'Read_me'" '(1856 characters)'
  102. if test -f 'Read_me'
  103. then
  104.     echo shar: will not over-write existing file "'Read_me'"
  105. else
  106. sed 's/^X//' << \SHAR_EOF > 'Read_me'
  107. Read_me: $Header: Read_me,v 1.3 85/08/12 17:11:36 roy Rel $
  108.  
  109.     This little package allows you to use run-time memory allocation
  110. for 2-dimensional arrays in a C program.  It works under 4.2bsd, but has
  111. not been tested under other systems, so I can't guarantee that it works
  112. under Sys5 or whatever.  Come to think of it, I can't guarantee that it
  113. even works under 4.2bsd, but as far as I can tell, there aren't any
  114. problems.
  115.  
  116.     Don't worry about the RCS stuff in the Makefile, I'm not
  117. distributing the RCS files, just the (so called) working files.  All you
  118. should have to do to get this running is un-shar it and utter "make test".
  119. Once you have satisfied yourself that it works, add arrayalloc.o to the
  120. appropriate library.  Probably /lib/libc.a is the right place, but you may
  121. prefer to put it in a local library; in fact, this may indeed be the wise
  122. thing to do.  Hey, if some random gave me some funny looking code, I
  123. wouldn't jump to stick it in *my* system library until I was sure I trusted
  124. it.  When you run the test program, you should get output which looks like
  125. this:
  126.  
  127.     0    1    2    3    4
  128.     10    11    12    13    14
  129.     20    21    22    23    24
  130.     30    31    32    33    34
  131.     40    41    42    43    44
  132.  
  133.     Of course, if you find any bugs, please let me know so I can fix
  134. things up.  This passes lint without any problems other than complaining
  135. about the rscid header lines; if you can figure out how to make lint shut
  136. up about that, tell me.  Actually, if you run lint with some of the more
  137. stringent checking turned on (-hc for example), it *does* get upset about
  138. most of the type casting, but I don't think it's anything to worry about.
  139. If you find that the type casting doesn't work on your machine, tell me;
  140. I'm not really a maven at these sorts of things.  In the meantime, enjoy.
  141.  
  142. Roy Smith <allegra!phri!roy>
  143. XSystem Administrator, Public Health Research Institute
  144. 455 First Avenue, New York, NY 10016
  145. SHAR_EOF
  146. if test 1856 -ne "`wc -c < 'Read_me'`"
  147. then
  148.     echo shar: error transmitting "'Read_me'" '(should have been 1856 characters)'
  149. fi
  150. fi # end of overwriting check
  151. echo shar: extracting "'arrayalloc.3'" '(1667 characters)'
  152. if test -f 'arrayalloc.3'
  153. then
  154.     echo shar: will not over-write existing file "'arrayalloc.3'"
  155. else
  156. sed 's/^X//' << \SHAR_EOF > 'arrayalloc.3'
  157. X.\"
  158. X.\" $Header: arrayalloc.3,v 1.1 85/08/12 16:56:20 roy Rel $
  159. X.\"
  160. X.\" $Log:    arrayalloc.3,v $
  161. Revision 1.1  85/08/12  16:56:20  roy
  162. Initial revision
  163.  
  164. X.\"
  165. X.TH ARRAYALLOC 3 "12 August 1985 (PHRI)"
  166. X.SH NAME
  167. arrayalloc, arrayfree \- 2-d array run-time memory allocation 
  168. X.SH SYNOPSIS
  169. X.B v = arrayalloc (imax, jmax, size)
  170. X.br
  171. X.B char **v, **arrayalloc();
  172. X.br
  173. X.B unsigned imax, jmax, size;
  174. X.sp
  175. X.B (void) arrayfree (v)
  176. X.br
  177. X.B char **v;
  178. X.SH DESCRIPTION
  179. Arrayalloc (imax, jmax, size) returns a pointer which can be thought of as
  180. pointing to a 2-dimensional array with imax rows and jmax columns, each
  181. element of which is size bytes long.  In reality, the pointer points to the
  182. address vector of a vectored array, but after being cast to the proper
  183. type, you can access the array with the familiar syntax v[i][j], just as if
  184. it were a true multi-dimensional array.
  185. X.SH SEE ALSO
  186. Run Time Memory Allocation for Multi-Dimensional Arrays in C.
  187. X.SH DIAGNOSTICS
  188. If sufficient memory is not available for either the main array or the
  189. intermediate address vector, NULL is returned.
  190. X.SH BUGS
  191. I haven't found any yet, but I wouldn't be too surprised if you do.
  192. In particular, this has only been tested on a Vax-11/750 running 4.2bsd Unix.
  193. That does not mean it's going to work on your Widget-9000 running Barfix, but
  194. I don't see any reason why it shouldn't.
  195. X.SH AUTHOR
  196. Roy Smith, Public Health Research Institue <allegra!phri!roy>.
  197. X.SH ACKNOWLEDGEMENTS
  198. This software was developed with funding from various federal
  199. research grants, notably AI 09049 from the National Institutes of Health
  200. and PCM 83-13516 from the National Science Foundation.  Their support is
  201. gratefully acknowledged.
  202. SHAR_EOF
  203. if test 1667 -ne "`wc -c < 'arrayalloc.3'`"
  204. then
  205.     echo shar: error transmitting "'arrayalloc.3'" '(should have been 1667 characters)'
  206. fi
  207. fi # end of overwriting check
  208. echo shar: extracting "'arrayalloc.c'" '(2312 characters)'
  209. if test -f 'arrayalloc.c'
  210. then
  211.     echo shar: will not over-write existing file "'arrayalloc.c'"
  212. else
  213. sed 's/^X//' << \SHAR_EOF > 'arrayalloc.c'
  214. /*
  215.  * Arrayalloc.c -- routines to provide dynamic memory allocation for 2
  216.  * dimensional arrays.  The idea is to implement vectored arrays in such a
  217.  * way that they are compatible with normal multi-dimension arrays as far
  218.  * as syntax goes.
  219.  *
  220.  * $Log:    arrayalloc.c,v $
  221.  * Revision 1.4  85/08/12  12:36:27  roy
  222.  * Random commenting and de-lintifying.
  223.  * 
  224.  * Revision 1.3  85/08/12  12:12:51  roy
  225.  * Added random comments in preperation for distribution.
  226.  * 
  227.  * Revision 1.2  85/08/06  18:30:27  roy
  228.  * Added debugging statments in arrayalloc().
  229.  * 
  230.  * Revision 1.1  85/08/05  18:45:20  roy
  231.  * Initial revision
  232.  * 
  233.  */
  234.  
  235. # include <stdio.h>
  236.  
  237. static char *rcsid = "$Header: arrayalloc.c,v 1.4 85/08/12 12:36:27 roy Rel $";
  238.  
  239. /*
  240.  * Arrayalloc () -- allocate an imax by jmax vectored array of "size" byte
  241.  * elements.  If memory can't be allocated, either for the main array or for
  242.  * the row address vector, we return NULL.  See accompanying documentation
  243.  * for more details.
  244.  */
  245. char **arrayalloc (imax, jmax, size)
  246. unsigned imax, jmax, size;
  247. {
  248.     char *malloc();
  249.     register char **vector, *array;
  250.     register int k, stride;
  251.  
  252.     /*
  253.      * Get memory for main array.
  254.      */
  255.     if ((array = malloc (imax * jmax * size)) == NULL)
  256.         return (NULL);
  257.  
  258. # ifdef DEBUG
  259.     printf ("array = %x\n", array);
  260. # endif
  261.  
  262.     /*
  263.      * Get memory for intermediate row address vector.
  264.      */
  265.     if ((vector = (char **) malloc (imax * sizeof (char *))) == NULL)
  266.         return (NULL);
  267.  
  268.     /*
  269.      * Initialize the address vector so each element points to the
  270.      * first element in the corresponding row in the main array.
  271.      */
  272.     for (k = 0; k < imax; k++)
  273.     {
  274.         stride = jmax * size;
  275.         vector [k] = &array [k*stride];
  276. # ifdef DEBUG
  277.         printf ("vector [%d] = %x\n", k, vector[k]);
  278. # endif
  279.     }
  280.  
  281.     return (vector);
  282. }
  283.  
  284. /*
  285.  * Arrayfree () -- free the memory acquired from arrayalloc ().  No checks
  286.  * are made to make sure things are as they should be, so it is the user's
  287.  * responsibility to make sure that you don't arrayfree() anything that you
  288.  * didn't arrayalloc() in the first place.  Eventually, checks will be added
  289.  * to make sure the user hasn't screwed things up.  We have to first free the
  290.  * real array memory, and then free the intermediate vector.  This sounds
  291.  * more complicated than it really is.
  292.  */
  293. arrayfree (v)
  294. char **v;
  295. {
  296.     free (v[0]);
  297.     free ((char *) v);
  298. }
  299. SHAR_EOF
  300. if test 2312 -ne "`wc -c < 'arrayalloc.c'`"
  301. then
  302.     echo shar: error transmitting "'arrayalloc.c'" '(should have been 2312 characters)'
  303. fi
  304. fi # end of overwriting check
  305. echo shar: extracting "'arrayalloc.me'" '(5356 characters)'
  306. if test -f 'arrayalloc.me'
  307. then
  308.     echo shar: will not over-write existing file "'arrayalloc.me'"
  309. else
  310. sed 's/^X//' << \SHAR_EOF > 'arrayalloc.me'
  311. X.\" arrayalloc.me -- arrayalloc and arrayfree documentation
  312. X.\" $Header: arrayalloc.me,v 1.5 85/08/12 19:38:55 roy Rel $
  313. X.\"
  314. X.\" $Log:    arrayalloc.me,v $
  315. \" Revision 1.5  85/08/12  19:38:55  roy
  316. \" fixed problems with formatting of abstract.  Why do I have to do this
  317. \" stuff right before I'm ready to send it out???
  318. \" 
  319. \" Revision 1.4  85/08/12  16:57:11  roy
  320. \" Added abstract
  321. \" 
  322. \" Revision 1.3  85/08/12  11:58:34  roy
  323. \" Changed name of file from vectors.me to arrayalloc.me
  324. \" 
  325. \" Revision 1.2  85/08/06  13:57:18  roy
  326. \" Diddled with formatting of Figure 1.
  327. \" 
  328. \" Revision 1.1  85/08/05  18:47:46  roy
  329. \" Initial revision
  330. \" 
  331. X.\"
  332. X.ll 6.5i
  333. X.ce
  334. X.ul
  335. Run Time Memory Allocation for Multi-Dimensional Arrays in C.
  336. X.sp
  337. X.(q
  338. X.ce
  339. X.ul
  340. Abstract
  341. X.sp
  342. Using the standard facilities available, there is no easy way to have
  343. 2-dimensional arrays in C with storage allocated at run time.
  344. This paper describes a simple to use, higher level interface to the standard
  345. library memory allocation routines which makes run time allocation of
  346. 2-dimensional arrays straight forward.
  347. The syntax for accessing these arrays is identical to that used for
  348. "regular" 2-dimensional arrays using compile time memory allocation.
  349. X.)q
  350. X.pp
  351. Due to the way that C treats arrays and pointers, the following two
  352. fragments are interchangeable in many applications.
  353. X.(b L
  354. X.(c
  355. X.sp
  356. int i, *v;                int i, v[10];
  357. v = malloc (10 * sizeof (int));        i = v[0];
  358. i = v[0];
  359. X.sp
  360. X.)c
  361. X.)b
  362. Once the memory is allocated (either at run time as in the first example,
  363. or at compile time as in the second), the syntax used to refer to an
  364. element in the array is the same.
  365. X.pp
  366. Unfortunately, this dynamic memory allocation scheme does not extend easily
  367. to multi-dimensional arrays.  To resolve a reference of the form
  368. X.rb a[i][j] ,
  369. where
  370. X.rb a
  371. has been declared as
  372. X.rb "int a[Imax][Jmax]"
  373. you effectively pretend the declaration was
  374. X.rb "int a[Imax*Jmax]"
  375. and turn the reference into
  376. X.rb a[Imax*i+j] .
  377. Given the way C deals with multi-dimensional arrays, this implies that Imax
  378. must be known at compile time.  Thus, you cannot directly use the standard
  379. dynamic memory allocators for run-time sizing of multi-dimensional arrays.
  380. X.pp
  381. The alternative is to use vectored arrays, where instead of performing the
  382. subscript multiplication, you pre-compute the addresses of all the rows in
  383. the array, store them, and look them up as needed (see figure 1).  Now,
  384. instead of
  385. X.rb a[imax*i+j] ,
  386. you have
  387. X.rb a[x[i]+j] ,
  388. where
  389. X.rb x
  390. is the intermediate row address lookup table.  Fortunately, the C syntax
  391. for dealing with arrays and pointers makes this type of data structure
  392. relatively painless to use once the initial address vector is constructed.
  393. As in the example above for one-dimensional arrays, the written expression
  394. for a true two-dimensional array is identical for that for the vectored
  395. array version.  Of course, the scheme can be extended to handle
  396. multi-dimensional array of order higher than 2; the details are left as an
  397. exercise for the reader.
  398. X.(z
  399. X.(c
  400. X.sp 2
  401.    +----------+             +----------+             +-----------+
  402.    |    a     | ----------> |   a[0]   | ----------> |  a[0][0]  |
  403.    +----------+             +----------+             +-----------+
  404.                             |   a[1]   | ----+       |  a[0][1]  |
  405.                             +----------+     |       +-----------+
  406.                                              |       |  a[0][2]  |
  407.                                              |       +-----------+
  408.                                              +-----> |  a[1][0]  |
  409.                                                      +-----------+
  410.                                                      |  a[1][1]  |
  411.                                                      +-----------+
  412.                                                      |  a[1][2]  |
  413.                                                      +-----------+
  414. X.sp
  415. XFigure 1.  A vectored array, \fBa[2][3]\fP.
  416. X.sp 2
  417. X.)c
  418. X.)z
  419. X.pp
  420. All that remains is a way to set up the proper intermediate address vector.
  421. The routine
  422. X.rb arrayalloc()
  423. does just this (for arrays of order 2).  You give it the the number of rows
  424. and columns and the size of each element; it allocates the needed memory
  425. and returns a pointer to the properly initialized address vector.  After
  426. casting to the proper type, this pointer can be used to access the array in
  427. the normal fashion.  Note that the while the syntax is similar to the
  428. familiar
  429. X.rb char **argv
  430. used to transmit program arguments as an array of strings, the intermediate
  431. address vector
  432. X.ul
  433. is not
  434. a null terminated list.  The above examples have assumed
  435. X.rb int 's
  436. but there is no reason why this must be so.  Array of other types, even
  437. derived types such as structures, will work just as well.
  438. X.pp
  439. As with everything else in life, there are advantages and disadvantages to
  440. vectored arrays.  On the plus side, it is usually faster to perform a
  441. pointer indirection than a multiplication.  I'm sure there is a machine out
  442. there somewhere which can do integer multiplication (perhaps by a power of
  443. 2) faster than it can do an indirect memory reference, but I've never seen
  444. one.  On the minus side, you need more memory because you have to store the
  445. intermediate address vector somewhere.  You can reduce this overhead
  446. somewhat for non-square arrays (i.e. where Imax != Jmax) by making Imax the
  447. smaller dimension.
  448. SHAR_EOF
  449. if test 5356 -ne "`wc -c < 'arrayalloc.me'`"
  450. then
  451.     echo shar: error transmitting "'arrayalloc.me'" '(should have been 5356 characters)'
  452. fi
  453. fi # end of overwriting check
  454. echo shar: extracting "'arrayalloc.txt'" '(4852 characters)'
  455. if test -f 'arrayalloc.txt'
  456. then
  457.     echo shar: will not over-write existing file "'arrayalloc.txt'"
  458. else
  459. sed 's/^X//' << \SHAR_EOF > 'arrayalloc.txt'
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.   Run Time Memory Allocation for Multi-Dimensional Arrays in C.
  468.  
  469.  
  470.                             Abstract
  471.  
  472.     Using the standard facilities available, there is no easy
  473.     way  to have 2-dimensional arrays in C with storage allo-
  474.     cated at run time.  This paper describes a simple to use,
  475.     higher level interface to the standard library memory al-
  476.     location routines which makes run time allocation  of  2-
  477.     dimensional  arrays straight forward.  The syntax for ac-
  478.     cessing these arrays is identical to that used for "regu-
  479.     lar" 2-dimensional arrays using compile time memory allo-
  480.     cation.
  481.  
  482.  
  483.      Due to the way that C treats arrays and pointers,  the  fol-
  484. lowing two fragments are interchangeable in many applications.
  485.  
  486.  
  487.       int i, *v;                              int i, v[10];
  488.       v = malloc (10 * sizeof (int));         i = v[0];
  489.       i = v[0];
  490.  
  491.  
  492. Once the memory is allocated (either at run time as in the  first
  493. example, or at compile time as in the second), the syntax used to
  494. refer to an element in the array is the same.
  495.  
  496.      Unfortunately, this dynamic memory  allocation  scheme  does
  497. not  extend  easily  to  multi-dimensional  arrays.  To resolve a
  498. reference of the form a[i][j], where a has been declared  as  int
  499. a[Imax][Jmax]  you  effectively  pretend  the declaration was int
  500. a[Imax*Jmax] and turn the reference into a[Imax*i+j].  Given  the
  501. way C deals with multi-dimensional arrays, this implies that Imax
  502. must be known at compile time.  Thus, you cannot directly use the
  503. standard  dynamic memory allocators for run-time sizing of multi-
  504. dimensional arrays.
  505.  
  506.      The alternative is to use vectored arrays, where instead  of
  507. performing  the  subscript  multiplication,  you  pre-compute the
  508. addresses of all the rows in the array, store them, and look them
  509. up  as  needed  (see figure 1).  Now, instead of a[imax*i+j], you
  510. have a[x[i]+j], where x is the intermediate  row  address  lookup
  511. table.   Fortunately,  the  C  syntax for dealing with arrays and
  512. pointers makes this type of data structure relatively painless to
  513. use  once  the  initial address vector is constructed.  As in the
  514. example above for one-dimensional arrays, the written  expression
  515. for  a  true  two-dimensional array is identical for that for the
  516. vectored array version.  Of course, the scheme can be extended to
  517. handle  multi-dimensional  array  of  order  higher  than  2; the
  518. details are left as an exercise for the reader.
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.  
  532.  
  533.  
  534.  
  535.    +----------+             +----------+             +-----------+
  536.    |    a     | ----------> |   a[0]   | ----------> |  a[0][0]  |
  537.    +----------+             +----------+             +-----------+
  538.                             |   a[1]   | ----+       |  a[0][1]  |
  539.                             +----------+     |       +-----------+
  540.                                              |       |  a[0][2]  |
  541.                                              |       +-----------+
  542.                                              +-----> |  a[1][0]  |
  543.                                                      +-----------+
  544.                                                      |  a[1][1]  |
  545.                                                      +-----------+
  546.                                                      |  a[1][2]  |
  547.                                                      +-----------+
  548.  
  549. XFigure 1.  A vectored array, a[2][3].
  550.  
  551.  
  552.  
  553.      All that remains is a way to set up the proper  intermediate
  554. address  vector.   The  routine  arrayalloc() does just this (for
  555. arrays of order 2).  You give it  the  the  number  of  rows  and
  556. columns  and  the  size  of each element; it allocates the needed
  557. memory and returns a pointer to the properly initialized  address
  558. vector.   After  casting  to the proper type, this pointer can be
  559. used to access the array in the normal fashion.   Note  that  the
  560. while  the  syntax  is similar to the familiar char**argv used to
  561. transmit program arguments as an array of strings, the intermedi-
  562. ate  address  vector  is  not  a null terminated list.  The above
  563. examples have assumed int's but there is no reason why this  must
  564. be  so.   Array of other types, even derived types such as struc-
  565. tures, will work just as well.
  566.  
  567.      As with everything else in life, there  are  advantages  and
  568. disadvantages  to  vectored arrays.  On the plus side, it is usu-
  569. ally faster to perform a pointer indirection than  a  multiplica-
  570. tion.   I'm sure there is a machine out there somewhere which can
  571. do integer multiplication (perhaps by a power of 2)  faster  than
  572. it  can do an indirect memory reference, but I've never seen one.
  573. On the minus side, you need more memory because you have to store
  574. the  intermediate  address vector somewhere.  You can reduce this
  575. overhead somewhat for non-square arrays (i.e. where Imax != Jmax)
  576. by making Imax the smaller dimension.
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590. SHAR_EOF
  591. if test 4852 -ne "`wc -c < 'arrayalloc.txt'`"
  592. then
  593.     echo shar: error transmitting "'arrayalloc.txt'" '(should have been 4852 characters)'
  594. fi
  595. fi # end of overwriting check
  596. echo shar: extracting "'test.c'" '(1221 characters)'
  597. if test -f 'test.c'
  598. then
  599.     echo shar: will not over-write existing file "'test.c'"
  600. else
  601. sed 's/^X//' << \SHAR_EOF > 'test.c'
  602. /*
  603.  * Arraytest.c -- driver program to exercise array allocation routine.
  604.  * All this does is get an array, fill it with numbers, print it all
  605.  * again, and then free the array.  This is as much a demo of how to use
  606.  * the routines as a test of how well they work.
  607.  *
  608.  * $Log:    test.c,v $
  609.  * Revision 1.3  85/08/12  19:21:06  roy
  610.  * Fixed trivial little typo in comment.  Of course, I only noticed the typo
  611.  * *after* I had already checked out the last version, marked it for release,
  612.  * built the sharchive, and was all ready to mail it off.  Grrrrrrrr.....
  613.  * 
  614.  * Revision 1.2  85/08/12  17:23:58  roy
  615.  * fixed botch in the " $ H e a d e r $ " line.
  616.  * 
  617.  * Revision 1.1  85/08/12  12:37:16  roy
  618.  * Initial revision
  619.  * 
  620.  */
  621.  
  622. static char *rcsid = "$Header: test.c,v 1.3 85/08/12 19:21:06 roy Rel $";
  623.  
  624. # include <stdio.h>
  625. # define MAX    5
  626. main ()
  627. {
  628.     char **arrayalloc();
  629.     int **x, i, j;
  630.  
  631.     if ((x = (int **) arrayalloc (MAX, MAX, sizeof (**x))) == NULL)
  632.     {
  633.         perror ("error in makearray: ");
  634.         exit (1);
  635.     }
  636.  
  637.     for (i = 0; i < MAX; i++)
  638.         for (j = 0; j < MAX; j++)
  639.             x[i][j] = 10*i + j;
  640.  
  641.     for (i = 0; i < MAX; i++)
  642.         for (j = 0; j < MAX; j++)
  643.             printf ("%d%c", x[i][j], j == MAX-1 ? '\n' : '\t');
  644.  
  645.     arrayfree ((char **) x);
  646. }
  647. SHAR_EOF
  648. if test 1221 -ne "`wc -c < 'test.c'`"
  649. then
  650.     echo shar: error transmitting "'test.c'" '(should have been 1221 characters)'
  651. fi
  652. fi # end of overwriting check
  653. #    End of shell archive
  654. exit 0
  655.