Listing 1

/*********************************************
* CreatRec.C
*
*  A method of handling the complex memory
*  allocation required to create an array of
*  character arrays in memory
*
*  The function declaration required is:
*    char **CreateRecord(int nfields,
*               int flen[], int InitString);
*  where: nfields is the number of fields or
*      strings to be created; flen[] is an
*      array of nfields-many ints, where each
*      array element is the desired length
*      of the corresponding field; InitString
*      is the value to use when initializing the
*      string space allocated by the function.
*
*  Returns: (char **).
*  The programmer should use this pointer to
*  access the strings created, and to free the
*  allocated memory when finished.
**********************************************/

#include <stdio.h>
#include <conio.h>
#include <alloc.h>
#include <mem.h>
#include <stdlib.h>

char **CreateRecord(int nfields, int flen[],
                int InitString)
{
   char **field; /* this value is returned */
   char *p;
   int i=0, recsize=0, memsize;

   while(i<nfields){
       recsize += flen[i++]; /* sum field sizes */
       }
   recsize += nfields; /* add space for a
                    terminator for each field */

   /* total to allocate includes space for strings
      and pointers to them: */
   memsize = nfields*sizeof(char *) +
                 recsize*sizeof(char);
   field = (char **)malloc(memsize);
   if(!field){
       #ifdef ERR_INTERNAL
           puts("Malloc failure in CreateRecord()");
           exit(1); /* abort on failure */
       #else
           return NULL; /* return warning */
       #endif
       }
   /* initialize strings */
   memset(field, InitString,memsize);

   /* set p to point to the first byte
      beyond the last pointer needed: */
   p = (char *)&field[nfields];
   for(i=0; i<nfields; i++){
       field[i] = p;   /* initialize the
                       pointer array */
       p = &p[ flen[i] ]; /* get address of
                      last char of the field */
       *p = '\0'; /* terminate the string */
       p++; /* next string start address */
       }
   return field;
}  /* CreateRecord() */

/**************************************************
* A Example of a Routine that Uses CreateRecord()
**************************************************/

#define ArraySize(x) ( sizeof(x)/sizeof(x[1]) )

/* by ArtS: October, 1990. a general purpose
 * macro to provide a count of the number of
 * elements in any given array. NOTE that this
 * works for
 *   char c[] = "Art was here"; ...c is an array
 * but NOT for
 * char *c = "Art was here"; ...c is a pointer!
 */

#define SPACE 32

char **CreateRecord(int nfields, int flen[],
                 int InitString);

/* A sample database fieldset: */
char *label[] = {
   "    FName",
   "    LName",
   "  Address",
   "     City",
   "    State",
   "      Zip",
   "  Remarks"
   };
/* Field lengths for sample database: */
int array[] = {20, 20, 30, 25, 2, 10, 50};


void main(void)
{
   char **set;
   int fieldcount;
   int i;

   puts("\nSample calls to CreateRecord() \
for allocating string arrays\n");

   puts("Initialize a database record \
to blanks:");

   fieldcount = ArraySize(array);
   set = CreateRecord(fieldcount, array, SPACE);
   if(!set){
      printf("Error allocating memory for record\n");
      exit(1);
      }
   for(i=0; i<fieldcount; i++){
      printf(" %s: [%s]\n", label[i], set[i] );
      }
   puts("\nPress Key..."); getch();
   free(set);

   puts("Initialize a database record to \
underline characters:");

   fieldcount = ArraySize(array);
   set = CreateRecord(fieldcount, array, '_');
   if(!set){
      printf("Error allocating memory for record\n");
      exit(1);
      }
   for(i=0; i<fieldcount; i++){
      printf(" %s: [%s]\n", label[i], set[i] );
      }
   puts("\nPress Key..."); getch();
   free(set);

   puts("Initiatize a set of five strings of \
length 12 to 'A':");
   for(i=0; i<5; i++){
     array[i] = 12; /* set field lengths to 12 */
     }
   set = CreateRecord(5, array, 'A' );
   if(!set){
      printf("Error allocating memory for record\n");
      exit(1);
      }
   for(i=0; i<5; i++){
      printf(" item %d: [%s]\n", i, set[i] );
      }
free(set);
}/* main */