                      C DYNAMIC MEMORY ALLOCATION

                            Matthew Probert
                           Servile  Software


If a program needs a table of data, but the size of the table is 
variable, perhaps for a list of all file names in the current 
directory, it is inefficient to waste memory by declaring a data table 
of the maximum possible size. Rather it is better to dynamically 
allocate the table as required. 

Also, since the 80x86 family of processors (when operating in DOS 
mode) are limited to a 64K data segment, with dynamic memory 
allocation a table can exceed 64K bytes in length.

C allocates RAM as being available for dynamic allocation into an area 
called the "heap". The size of the heap varies with memory model. The 
tiny memory model defaults to occupy 64K of RAM. The small memory 
model allocates upto 64K for the program/code and heap with a far heap 
being available within the remainder of conventional memory. The other 
memory models make all conventional memory available to the heap. This 
is significant when programming in the tiny memory model when you want 
to reduce the memory overhead of your program to a minimum. The way to 
do this is to reduce the heap to a minimum size. The smallest is 1 
byte. 

C provides a function malloc() which allocates a block of free memory 
of a specified size and returns a pointer to the start of the block; 
it also provides free() which deallocates a block of memory previously 
allocated by malloc(). Notice, however, that when DOS is asked to 
allocate a block of memory, it searches for a contiguous free area of 
memory long enough to accomodate the requested block. This results in 
memory becoming fragmented, and contiuous use of malloc() and free() 
may eventually result in no contiguous memory blocks being large 
enough to satisfy further malloc() requests.

This program searches a specified file for a specified string (with 
case sensitivity). It uses malloc() to allocate just enough memory for 
the file to be read into memory. 

#include <stdio.h> 
#include <stdlib.h> 

char *buffer; 

void main(int argc, char *argv[]) 
{ 
    FILE *fp; 
    long flen; 

    /* Check number of parameters */ 
    if (argc != 3)
    { 
        fputs("Usage is sgrep <text> <file spec>",stderr); 
        exit(0); 
    } 

    /* Open stream fp to file */ 
    fp = fopen(argv[2],"r"); 
    if (!fp)
    { 
        perror("Unable to open source file"); 
        exit(0); 
    } 

    /* Locate file end */ 
    if(fseek(fp,0L,SEEK_END))
    { 
        fputs("Unable to determine file length",stderr); 
        fclose(fp);
        exit(0); 
    } 

    /* Determine file length */ 
    flen = ftell(fp); 

    /* Check for error */ 
    if (flen == -1L)
    { 
        fputs("Unable to determine file length",stderr); 
        fclose(fp);
        exit(0); 
    } 

    /* Set file pointer to start of file */ 
    rewind(fp); 

    /* Allocate memory buffer */ 
    buffer = malloc(flen); 

    if (!buffer)
    { 
        fputs("Unable to allocate memory",stderr); 
        fclose(fp);
        exit(0); 
    } 

    /* Read file into buffer */ 
    fread(buffer,flen,1,fp); 

    /* Check for read error */ 
    if(ferror(fp))
    { 
        fputs("Unable to read file",stderr); 

        /* Deallocate memory block */
        free(buffer); 

        fclose(fp);
        exit(0); 
    } 

    printf("%s %s in %s",argv[1],(strstr(buffer,argv[1])) ? "was found" : 
                  "was not found",argv[2]); 

    /* Deallocate memory block before exiting */
    free(buffer); 
    fclose(fp); 
} 


