13.4. Dynamic Memory Allocation and Swarm Zones

Veteran C programmers have no doubt tangled with the problem of dynamic memory allocation using malloc or calloc. In its Zone protocol, Swarm has methods that can be used in place of these functions. While there is nothing inherently wrong with using the built-in C functions to allocate memory, there are some advantages in the Swarm methods that may reduce the danger of memory leaks.

Swarm users who are not familiar with dynamic memory allocation may wish to consult a C manual. In a nutshell, the problem is this. If one wants to create an array, the elementary way to do so is to declare the array like so:

int array[5]; 

This creates an array of 5 integers. When the program runs, memory is set aside where values can be placed into and retrieved from the array.

This standard approach only works when the user knows that there will be exactly 5 elements in the array. What if some calculations are done during the run of the program and then it is necessary to create an array that depends on that calculated number? This is the kind of case for which dynamic memory allocation is needed. If, during a run, some number N is calculated, and then one needs to have an array of length N, then the program can grab some of the system's physical memory and use it.

Dynamic memory in Swarm can be accessed by the methods alloc: and allocBlock: in Swarm's Zone protocol. First, it is necessary to declare a pointer that will serve as the address of the dynamically allocated memory. Second, the memory is allocated to that pointer. Here is an example from a class called Point, which is used to dynamically allocate space for arrays of real numbers.

//Point.h
@interface Point: SwarmObject {
        double * position;
        int spaceSize;
 }

-buildObjects;
-(void) drop;
-setSpaceSize:(int) size;


//Point.m
#import Point.h

@implementation Point

- buildObjects
{
  //position = xmalloc(spaceSize * sizeof(double));
  //Test to make sure the memory was allocated. If not, exit immediately
  //if(position==NULL) exit(8);
   position = [[self getZone] allocBlock: spaceSize * sizeof(double)];
   return self;
}
- (void)drop
{
  //free(position);
  [[self getZone] freeBlock: position blockSize: spaceSize * sizeof(double)];
  [super drop];
}

- setSpaceSize: (int)size
{
  spaceSize=size;
  return self;
}

Note that for the C programmer's information there are commented-out versions of malloc and free calls.

When a user wants to use the Point class to create a new Point, which has an array of doubles inside it, then an instance of the Point class is created in the usual Swarm way. Then the size is set, and then the Point is told to build its objects, which allocates the dynamic memory. For example:

	id  newPoint;

	newPoint=[Point createBegin: [self getZone];
	newPoint= [newPoint createEnd:];
	[newPoint setSize: N];
	[newPoint buildObjects];
      

After that space is allocated, then it can be used by methods in the Point class as if it were an array. The reason that one can treat the pointer to the dynamically allocated memory as if it were an array is found in the fundamental similarity of pointers and arrays in C. Interested research should consult the C manuals for a comparision of pointers and arrays. To consider a usage example, a method could be written to fill the array with random numbers between 1 and 5.

- fillRandomly
{
  int i;

  for(i = 0, i < spaceSize; i++)
  {
    position[i]=[uniformDblRand getDoubleWithMin: 1 withMax: 5];
    return self;
  }
}

A memory leak is a flaw in a program which causes it to access dynamic memory and then "waste" it by dropping all references to it without letting the operating system know that the memory is no longer needed. In C, the free() function tells the operating system that the memory can be reallocated to other purposes. If the programmer forgets to free memory that is no longer needed, then the memory demands of the program will expand with each new allocation, taking memory that might be used by other applications and eventually causing the program to crash.

In Swarm, memory allocated with allocBlock: can be freed explicitly with the freeBlock: method. The usage of freeBlock: is illustrated in the drop method of the Point class. This drop method is used only to free the dynamic memory, but it would also explicitly drop any Swarm objects that were created inside the object. The topic of designing programs to avoid memory leaks is discussed further in the next section.