Heap Allocation and Deallocation
• The C programmer must run functions to allocate and deallocate memory for dynamic storage (referenced by pointers)
• malloc allocates a block of storage from the heap
• free returns storage to the heap
int *intPtr;
Declare a Pointer to an int
intPtr The variable is uninitialized and contains garbage, but it can point to an int eventually
#include <stdio.h>
int *intPtr = NULL; // NULL is the same as 0
Declare and Initialize to NULL
0
intPtr The variable is initialized to the NULL pointer, which can now be accessed
#include <stdlib.h>
int *intPtr = malloc(sizeof(int));
Declare and Initialize with malloc
intPtr The variable now points to a new storage area for an int, but this storage contains garbage
malloc expects an integer representing the size of the storage needed
The sizeof function takes a type as an argument and returns the number of bytes needed for a value of that type
malloc returns a pointer to the first byte of the storage
#include <stdlib.h>
int *intPtr = malloc(sizeof(int));(*intPtr) = 69;printf("%d\n", *intPtr);
Access via Dereference with *
intPtr The variable now points to storage that has a program-supplied value69
The * operator accesses the cell pointed to
The pointer must point to a cell
* has a lower precedence than =
#include <stdlib.h>
int *intPtr = malloc(sizeof(int));(*intPtr) = 69;printf("%d\n", *intPtr);free(intPtr);
Return the Storage with free
intPtr The variable still points to storage, which might be used by others69
The storage is still accessible, but might be taken for other applications (also called a dangling pointer reference)
#include <stdlib.h>
int *intPtr = malloc(sizeof(int));(*intPtr) = 69;printf("%d\n", *intPtr);free(intPtr);intPtr = NULL;
Reset the Pointer to null
0
intPtr The variable now has no dangling pointer69
Clean up by setting the pointer to NULL or to other storage
#include <stdlib.h>
int *intPtr = malloc(sizeof(int));(*intPtr) = 69;printf("%d\n", *intPtr);intPtr = NULL;
Be Careful of Memory Leaks!
0
intPtr
69
In this case, the storage cannot be accessed by the program, or by the heap manager, and will eventually result in heap underflow!
Always free your own storage!
Nodes and Linked Structures
data next data next
2
head
size
Could be a linked stack
How do we represent a node in C?
The C struct
• A struct is a data type that includes one or more named data fields
• Good for containing data of different types
• Like classes in Python or Java, but without the methods
struct point{ int x, y;} p1, p2;
Declare a Type and Two Variables
p1
Storage is automatically allocated when variables are declared
x
x
y
p2
y
struct point{ int x, y;} p1, p2;
p1.x = 44;p1.y = 55;
Initialize the Fields of p1
p1
The field selector (.) accesses a field for reference or assignment
x
55
44 x
y
p2
y
struct point{ int x, y;} p1, p2;
p1.x = 44;p1.y = 55;
p2 = p1;
Copy p1 to p2
55
p1
Unlike arrays, the contents of an entire struct can be assigned to another one44 x
55
44 x
y
p2
y
struct point{ int x, y;};
struct point p1, p2;
p1.x = 44;p1.y = 55;
p2 = p1;
Variation
55
p1
Can declare the type, then the variables later
44 x
55
44 x
y
p2
y
typedef struct point{ int x, y;} point;
point p1, p2;
p1.x = 44;p1.y = 55;
p2 = p1;
Create a Synonym with typedef
55
p1
This synonym happens to be the same name as the name of the struct44 x
55
44 x
y
p2
y
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
Declare a Node Type
No storage yet, because no variables have been declared
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
nodePtr ptr;
Declare a Pointer Variable to a Node
ptr ptr contains garbage
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
nodePtr ptr = malloc(sizeof(node));
Initialize It to a New Node
ptr malloc allocates storage for the entire node
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
nodePtr ptr = malloc(sizeof(node));
ptr->data = 69;ptr->next = NULL;
Initialize the Node’s Contents
ptr The -> operator combines * (dereference) and . (field selection)
69
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
nodePtr getNode(int data, nodePtr next){; nodePtr ptr = malloc(sizeof(node)); ptr->data = data; ptr->next = next; return ptr;}
Define a Helper Function getNode
This function creates a new node, initializes its contents, and returns a pointer to it
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
nodePtr getNode(int data, nodePtr next){; nodePtr ptr = malloc(sizeof(node)); ptr->data = data; ptr->next = next; return ptr;}
int i;nodePtr head = NULL;for (i = 1; i <= 3; i++) head = getNode(i, head);
Create a Linked Structure!
3 1head 2
typedef struct node{ int data; struct node *next;} node;
typedef node* nodePtr;
typedef struct linkedStack{ int size; nodePtr top;} linkedStack;
linkedStack newStack();
void push(linkedStack *stk, int data);
int pop(linkedStack *stk);
int size(linkedStack stk);
The Header File for a Linked Stack
linkedStack newStack(){ linkedStack stk; stk.top = NULL; stk.size = 0; return stk;}
void push(linkedStack *stk, int data){ stk->top = getNode(data, stk->top); stk->size = stk->size + 1;}
int pop(linkedStack *stk){ int data = stk->top->data; nodePtr garbage = stk->top; stk->top = stk->top->next; free(garbage); stk->size = stk->size - 1; return data;}
int size(linkedStack stk){ return stk.size;}
The Implementation
#include <stdio.h>
#include "stack.h"
int main(){ linkedStack stk = newStack(); int i; for (i = 1; i <= 5; i++) push(&stk, i); printf("The stack has %d elements\n", size(stk)); while (size(stk) > 0) printf("Popping %d\n", pop(&stk)); printf("The stack has %d elements\n", size(stk));}
Using the Linked Stack
Top Related