Re: arrays

From: Cervo (chrisf@PTD.NET)
Date: 10/07/98


> Is there a way to dynamically create an array of integers? Like I can malloc
> what I need for a struct on the fly, but I need to do so for a simple array.
> eg, I have array[10][10][10] which consumes lots of ram and may not be
> needed. I might need 10, I might need 5.
> This is probably such a simple thing, Ill be embarrassed, but for the life
> of me I can't find the answer...
>
> Erik Madison
> ICQ #13940294
> fafhrd@rotd.com
to allocate a dynamic array of integers

int *vararray = (int) calloc(5, sizeof(int));

This allocates 5 integers, so you can go vararray[0] - vararray[4].  It
can easily be expanded to be realloced, or copied to a temporary array and
then re calloced, then have the data copied from the temp array back.
This way the array can grow or shrink.

If for some reason you don't keep track of the number of items in the
array, the way to tell how many of a datatype are allocated, use this
cheesy shortcut

sizeof(variable) / sizeof(datatype);

An example of this is we made an array and allocated space for twenty
integers

int *vararray = NULL;
vararray = (int) calloc(20, sizeof(int));

Somehow we forgot that we allocated 20 integers to the array, so we use
the shortcut explained above

sizeof(vararray)/ sizeof(int)

size_of_array = sizeof(vararray) / sizeof(int);

Bleh this is hard to explain, so I will make you an example program.  Of
course, I haven't compiled this and I am sure I left out a semi-colon or
two, or something like that, but you should get the general idea.

---------------------dynarray.c-----------------------------------
#include<stdio.h>
#include<stdlib.h>

int main() {
  int *array_of_ints = NULL, size_of_array = 0, array_size = 0;
  printf("How many integers do you wish the array to hold?\n");
  scanf("%d", array_size);
  array_of_ints = (int) calloc(array_size, sizeof(int));
  printf("Woohoo we just allocated an array of ints with a size of %d\n",
   array_size);
  size_of_array = sizeof(array_of_ints) / sizeof(int);
  printf("The size of the array is %d, hope it matches %d\n",
   size_of_array, array_size);
  free(array_of_ints);
  array_of_ints = NULL;
} /* End of main */
--------------------------------END-----------------------------------------
While much of this code is redundant, it does show a good example of
various methods for dealing with a "dynamic" array, which is really just a
pointer to a bunch of memory taken from the heap.  As far as the scanf, I
make no guarantees, generally I don't use it.  The program prompts the
user to enter the size of the array, into the integer variable array_size.
Then, it uses calloc to take some memory off of the stack and allocate
space for 20 integers.  Then the size of the array is calculated by taking
the size of the entire array in memory and then dividing it by the size of
one integer, which should theoretically(and does in reality) return how
many integer sized chunks of memory there are, hence the number of
integers.  Then the program prints out the size of the array that was
calculated, along with the size that was entered in.  If for some reason
the two sizes are different, there are some severe problems :)  Anyway at
the end it frees the memory occupied by the array by using the free
procedure.  To use calloc, malloc, realloc, and of course free you must
include stdlib.h.  As far as circle goes, if you use integer arrays, here
are some considerations.

1.  Check the calloc to see that the memory was allocated.  Something
like:

  if ( ( array_of_ints = calloc(30, sizeof(int)) ) == NULL ) {
    /* Allocation error, deal with it probably return from function with
    error */
  }

2.  Probably you will not always know the size of the array, so keeping in
mind the sizeof(array_of_ints) / sizeof(int) is a very good idea.

3.  Make sure that when you are done with the array it is freed, and then
set to NULL.

As far as accessing values in the array, standard array notation is fine

array_of_ints[0]
.
.
.
array_of_ints[19] or whatever.

In fact, these principles work with any datatype, from struct to char to
float, whatever you want.  In fact the create macro is a calloc with some
checking for memory allocation, so use the CREATE macro to make the array
if you are using circle.  something like CREATE(array_of_ints, int, 20);
or whatever.  I currently do not have a copy of circle's code sitting in
front of me, so I don't remember the exact order of arguments for the
CREATE macro, but using it is a MUCH better idea then just using a
straight calloc, because if for some reason you need to log memory usage,
this becomes much easier.

As a side note, you may already do this same exact thing with char *
variables and just have never thought about it being applicable to any
other datatypes, but a string is just an array of chars, so it works on
any array.

Just remember:
                   If you cannot convince them, confuse them.
                            -- Harry S. Truman

Hopefully I didn't do the latter :P

Cervo the redoC retsaM


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/15/00 PST