Allocating and Freeing Dynamic Variables in C

We create a pointer variable to an integer with the declaration int *p; Having declared a variable p as a pointer to a specific type, it is possible to dynamically create an object of that type and assign its address to p.

We do this by calling the standard library function malloc(), which dynamically allocates a portion of memory of a specified size and returns  a pointer to it.

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

int main(void){

    int *i, *j;

    int x;

    i = (int *) malloc(sizeof(int));

    *i = 1138;

    j = i;

    printf("%d %d\n", *i, *j);

    x = 73;

    *i = x;

    printf("%d %d\n", *i, *j);

    *i = 5;

    printf("%d %d\n", *i, *j);

    return 0;

}

The sizeof operator returns the size, in bytes, of its operand.  We can use sizeof in conjunction with malloc() to get an object of the proper size.

The free() function is used to return allocated storage. Calling free() on a pointer makes the memory pointed to by the pointer available for reuse.  While most operating systems “clean up” memory after a program exits, it’s still really a good idea to explicitly clean up any dynamically allocated memory ourselves.

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

int main(void){

    int *p = (int *)malloc(sizeof(int));
    int *q = (int *)malloc(sizeof(int));
    double *d = (double *)malloc(sizeof(double));
    double *e = (double *)malloc(sizeof(double));

    *p = 404;
    *q = 711;
    free(p);    
    p = q;
    printf("%d %d\n", *p, *q);
    
    *d = 0.57721;
    *e = 1.12358;

    printf("%f %f\n", *d, *e);

    free(e);
    e = d;
    *d += 7.11;

    printf("%f %f\n", *d, *e);

    //clean up time
    free(d);
    free(q);
        
    return 0;

}

As we have seen in these past two programs, if two pointers point at the same variable, they are functionally identical. Thus, an assignment to one changes the value of the other.

Next, let’s take a look at creating a linked list using dynamic variables. A linked list consists of a set of nodes, each of which has two fields: an information field and a pointer to the next node in the list. In addition, we have an external pointer that points to the first node in the list.

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

struct node * getNode();

struct node{
    int data;
    struct node *next;
};

int main(void){

    struct node *begin, *temp;    
    struct node *nodePtr;

    temp = getNode();
    temp->data = 42;
    
    begin = temp;
    nodePtr = temp;
    
    nodePtr->next = getNode();
    temp = nodePtr->next;

    temp->data = 73;
    nodePtr = temp;
    nodePtr->next = getNode();

    temp = nodePtr->next;
    temp->data = 1999;
    temp->next = NULL;

    nodePtr = begin;

    while(1){
        printf("%d\n", nodePtr->data);
        if(nodePtr->next==NULL){
            break;
        } else {
            nodePtr = nodePtr->next;
        }
    }
    
    return 0;

}

struct node * getNode(){
    struct node *p;
    p = (struct node *)malloc(sizeof(struct node));
    return p;
}

When looking at the above code, we should ask ourselves how we would go about returning all of the nodes’ memory to the heap.

Note that the getnode() function could as well be implemented via a macro.

Next, let’s look at implementing a list as a queue. A queue follows the first in, first out principle – the first item to be inserted into a queue, will also be the first to be taken out. To do this, we will create a second structure, known as a queue. This structure will have two fields; the first field will be a node pointer to the first node in the list, and the second pointer will be a pointer to the last node in the list.

Our function for getting a queue will initialize both of these fields to NULL. We will then implement two functions, pop() and push(). The pop() function takes a node out out of the queue, frees it in memory, and then returns the value it was storing. The push() function creates a new node, assigns its data field a value, and then assigns it to the end of the queue.

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

struct node *getNode();
struct queue * getQueue();
int empty(struct queue *q);
void push(struct queue *q, int x);
int pop(struct queue *q);

struct node{
    int data;
    struct node *next;
};

struct queue{
    struct node *first;
    struct node *last;
};

int main(void){
    struct queue *q = getQueue();
    printf("queue allocated.");
    if(empty(q)){
        printf("queue is empty.\n");
    }

    push(q, 2001);
    push(q, 2600);
    push(q, 80);
    push(q, 1970);
    push(q, 1701);

    while(empty(q)==0){
        printf("%d\n", pop(q));
    }


    return 0;    
}




struct node * getNode(){
    struct node *p;
    p = (struct node *)malloc(sizeof(struct node));
    return p;
}

struct queue * getQueue(){
    struct queue *q;
    q = (struct  queue*)malloc(sizeof(struct queue));
    q->first=NULL;
    q->last=NULL;
    return q;
}    

int empty(struct queue *q){
    if(q->first==NULL){
        return 1;
    } else {
        return 0;
    }
}

void push(struct queue *q, int x){
    struct node *n = getNode();
    n->data = x;
    n->next = NULL;
    if(q->last!=NULL){
        (q->last)->next = n;    
    } else {
        q->first = n;
    }
    q->last = n;
}

int pop(struct queue *q){
    int x;
    struct node *n = q->first;
    q->first = n->next;
    if(q->first==NULL){
        q->last=NULL;
    }
    x = n->data;
    free(n);
    return x;
}

One of the nice things about working with higher level languages such as C# is that data structures such as linked lists are already implemented for us in the language.

To learn more about C, take a look at my book at http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/

 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s