18
CSc 352 Freeing Dynamically Allocated Memory Saumya Debray Dept. of Computer Science The University of Arizona, Tucson [email protected]

CSc 352 Freeing Dynamically Allocated Memory Saumya Debray Dept. of Computer Science The University of Arizona, Tucson [email protected]

Embed Size (px)

Citation preview

CSc 352Freeing Dynamically Allocated Memory

Saumya DebrayDept. of Computer Science

The University of Arizona, [email protected]

Motivation

• Dynamically allocated memory should be freed when no longer needed– The C runtime system does not automatically reclaim

memory– memory leaks increase the program’s memory footprint

• this can lead to slow performance, program crashes

• This needs to be done with care:– too-aggressive freeing can lead to program errors– too-passive freeing can miss memory allocated “behind

the scenes”, e.g., through strdup().

2

Issues

• Understanding when dynamic memory allocation happens– explicit (by the programmer)– implicit (by library routines)

• Through the course of the program:– identifying when memory is no longer needed– being aware of multiple pointers to a block of memory

• Identifying and fixing memory leaks

3

Understanding dynamic memory allocation

• Dynamic allocation can be explicit or implicit– explicit: when the programmer invokes malloc, calloc, etc.– implicit: when the memory allocation happens “behind the

scenes” in a library routine• getline• strdup• GNU extension to scanf• fopen• …

In general, if memory appears “by magic” at runtime, chances are it’s being allocated implicitly.

4

Freeing up memory

• Use free(p) when a memory block is no longer needed– p is a pointer to a block of memory previously allocated

through malloc or calloc

5

• Pitfalls:– accessing a previously-

freed block is an error– freeing a block of

memory twice is an error

pointer

malloc’d memory

blockwatch out for multiple ways to reach a memory block

Freeing up memory

• General approach:– free up memory “hanging off” a block of memory– grab any pointers you need to traverse the rest of the data

structure– then free the block itself

6

1deallocate memory

“hanging off” this node

2grab this pointer

3free this block

Finding memory leaks 1

7

use valgrind to determine whether the program has memory leaks

Finding memory leaks 2

8

indicates where the lost memory was allocated

Finding memory leaks 2

9

forgot to fclose() after reading the file!

After fclose-ing the input stream

10

less leakage than before, but still quite a bit

need to free the linked list of states

Freeing up a linked list 1

11

naïve code to free the nodes in a linked list

Freeing up a linked list 2

12

st0 st1stateList

Freeing up a linked list 3

13

• no memory errors• less memory being leaked• but some leakage persists!

• reason: structures “hanging off” states not being freed

// a DFA statetypedef struct vertex { char *name; struct edge *transitions; bool isFinal; struct vertex *next;} state;

// a transition between statestypedef struct edge { char ch; struct vertex *from, *to; struct edge *next;} edge;

Freeing up a linked list 4

14

Solution: free up the edges “hanging off” each state before freeing hat state

Freeing up a linked list 4

15

a lot better!

but some leakage still left!

Freeing up a linked list 4

16

// a DFA statetypedef struct vertex { char *name; struct edge *transitions; bool isFinal; struct vertex *next;} state;

Freeing up a linked list 5

17

Summary

• Should free up dynamically allocated memory when done– Use valgrind to identify memory leak sources!

• Needs to be done carefully– freeing up “live” memory will result in program errors

• Pay attention to implicitly-allocated memory, e.g.:– file pointers– strings allocated through strdup()– when freeing up a struct, first free up any unused memory

“hanging off” the struct

18