Void Pointers
Using Void Pointers
Another Type of Memory
We already have two types of
memory
– Stack space : for values with a lifetime
tied to a single function execution
– Static space : for values with a lifetime
from the start to the end of the
program’s execution
* But, there’s another type of memory,
the heap
– The program says when it needs heap
memory (and how much)
– The program says when it’s done with a
particular value in heap memory
– Called: dynamic memory allocation
Asking for Heap Memory
Using malloc()
Freeing Memory
A program that reads and returns integers
int *readList -> here’s how we return a list of integers
int *len -> an integer passed by reference, it’s how we return the length
int *readList( int *len )
{
scanf( “%d”, len );
int *list = (int *)malloc( *len * sizeof( int ) );
for ( int i = 0; i < *len; i++ )
scanf( “%d”, list + i );
return list;
}
Client code:
* This is typical client code for readList().
int len;
int *list = readList( &len );
for ( int i = 0; i < len; i++ )
printf( “%d\n”, list[ i ] );
free( list )
Type and Ambiguity
Return Alternatives
Using Dynamically Allocated Memory(return and syntax)
void *malloc( size_t size );
void free( void *ptr );
* Memory returned by malloc() is uninitialized, it may contain garbage from a previous allocation
* Returns NULL on failure (e.g., if memory is full)
* Type size_t for representing the size of storage regions
– It’s what sizeof() evaluates to
– And what printf() prints with format string “%zd”
– Just another name for an integer type (unsigned long on the common platform)
Dynamic Allocation Hazards
Leaking Memory
Dangling Pointers
Other Mistakes in Using Dynamically Allocated Memory
Thinking about Dynamic Allocation(C v Java)
Thinking about Dynamic Allocation(why use malloc/free?)
Saving Strings
Resizing Arrays
Resizing Array(slow way)
int capacity = 5;
int len = 0;
int *list = (int *)malloc( capacity * sizeof( int ) );
int val;
while ( scanf( “%d”, &val ) == 1 ) {
if ( len >= capacity ) {
capacity += 1;
int *newList = (int *)malloc(capacity * sizeof(int));
for ( int i = 0; i < len; i++ )
newList[ i ] = list[ i ];
free( list );
list = newList;
}
list[ len++ ] = val;
}
Copying Memory
Resizing Array(better way)
int capacity = 5;
int len = 0;
int *list = (int *)malloc( capacity * sizeof( int ) );
int val;
while ( scanf( “%d”, &val ) == 1 ) {
if ( len >= capacity ) {
capacity *= 2;
int *newList = (int *)malloc(capacity * sizeof(int));
memcpy( newList, list, len * sizeof( int ) );
free( list );
list = newList;
}
list[ len++ ] = val;
}
More storage
overhead, but much
less time overhead.
Meet realloc()
Meet calloc()
Performance Comparison