Lab 08 - malloc and Friends

Similar documents
Lecture 10: Dynamic Memory Allocation 1: Into the jaws of malloc()

Lecture 11 Doubly Linked Lists & Array of Linked Lists. Doubly Linked Lists

Memory management. Announcements. Safe user input. Function pointers. Uses of function pointers. Function pointer example

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

Short Notes on Dynamic Memory Allocation, Pointer and Data Structure

Linked Lists, Stacks, Queues, Deques. It s time for a chainge!

Memory Allocation. Static Allocation. Dynamic Allocation. Memory Management. Dynamic Allocation. Dynamic Storage Allocation

Example 1/24. Example

ECS 165B: Database System Implementa6on Lecture 2

Chapter 5 Names, Bindings, Type Checking, and Scopes

ONE OF THE MOST JARRING DIFFERENCES BETWEEN A MANAGED language like PHP,

10CS35: Data Structures Using C

C Dynamic Data Structures. University of Texas at Austin CS310H - Computer Organization Spring 2010 Don Fussell

Object Oriented Software Design II

Stack Allocation. Run-Time Data Structures. Static Structures

Introduction to Data Structures

Storage Classes CS 110B - Rule Storage Classes Page 18-1 \handouts\storclas

Leak Check Version 2.1 for Linux TM

Lecture Data Types and Types of a Language

C++ INTERVIEW QUESTIONS

1 Abstract Data Types Information Hiding

Programming Embedded Systems

An Implementation of a Tool to Detect Vulnerabilities in Coding C and C++

How To Understand How A Process Works In Unix (Shell) (Shell Shell) (Program) (Unix) (For A Non-Program) And (Shell).Orgode) (Powerpoint) (Permanent) (Processes

Organization of Programming Languages CS320/520N. Lecture 05. Razvan C. Bunescu School of Electrical Engineering and Computer Science

7.1 Our Current Model

Coding Rules. Encoding the type of a function into the name (so-called Hungarian notation) is forbidden - it only confuses the programmer.

DATA STRUCTURES USING C

COMP 356 Programming Language Structures Notes for Chapter 10 of Concepts of Programming Languages Implementing Subprograms.

Object-Oriented Design Lecture 4 CSU 370 Fall 2007 (Pucella) Tuesday, Sep 18, 2007

Building Embedded Systems

Semantic Analysis: Types and Type Checking

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

Java Interview Questions and Answers

Programming languages C

MPI-Checker Static Analysis for MPI

Symbol Tables. Introduction

KITES TECHNOLOGY COURSE MODULE (C, C++, DS)

Lab Experience 17. Programming Language Translation

CSE 211: Data Structures Lecture Notes VII

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

Moving from CS 61A Scheme to CS 61B Java

Object Oriented Software Design II

Static Code Analysis Procedures in the Development Cycle

Node-Based Structures Linked Lists: Implementation

Glossary of Object Oriented Terms

The C Programming Language course syllabus associate level

1. The memory address of the first element of an array is called A. floor address B. foundation addressc. first address D.

A Memory Model for Static Analysis of C Programs

How To Write Portable Programs In C

Dalhousie University CSCI 2132 Software Development Winter 2015 Lab 7, March 11

Purify User s Guide. Version 4.1 support@rational.com

Comp151. Definitions & Declarations

Lecture 22: C Programming 4 Embedded Systems

Lecture 9. Semantic Analysis Scoping and Symbol Table

Scoping (Readings 7.1,7.4,7.6) Parameter passing methods (7.5) Building symbol tables (7.6)

Stacks. Linear data structures

Class Notes for CSCI 104: Data Structures and Object-Oriented Design

Parameter passing in LISP

PES Institute of Technology-BSC QUESTION BANK

Java Programming. Binnur Kurt Istanbul Technical University Computer Engineering Department. Java Programming. Version 0.0.

Introduction to Programming System Design. CSCI 455x (4 Units)

C Interview Questions

Get the Better of Memory Leaks with Valgrind Whitepaper

Install Java Development Kit (JDK) 1.8

IBM SDK, Java Technology Edition Version 1. IBM JVM messages IBM

Habanero Extreme Scale Software Research Project

Data Structures. Level 6 C Module Descriptor

MatrixSSL Porting Guide

Memory Debugging with TotalView on AIX and Linux/Power

The Advantages of Dan Grossman CSE303 Spring 2005, Lecture 25

Data Structure [Question Bank]

Input/Output Subsystem in Singularity Operating System

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Abstract Data Type. EECS 281: Data Structures and Algorithms. The Foundation: Data Structures and Abstract Data Types

CS 106 Introduction to Computer Science I

CmpSci 187: Programming with Data Structures Spring 2015

Chapter 13 Storage classes

Molecular Dynamics Simulations with Applications in Soft Matter Handout 7 Memory Diagram of a Struct

Trace-Based and Sample-Based Profiling in Rational Application Developer

Instrumentation Software Profiling

How to create/avoid memory leak in Java and.net? Venkat Subramaniam

1 The Java Virtual Machine

No no-argument constructor. No default constructor found

Getting Started with the Internet Communications Engine

CISC 181 Project 3 Designing Classes for Bank Accounts

Free Java textbook available online. Introduction to the Java programming language. Compilation. A simple java program

PART-A Questions. 2. How does an enumerated statement differ from a typedef statement?

Free Java textbook available online. Introduction to the Java programming language. Compilation. A simple java program

CS 241 Data Organization Coding Standards

Lab 2: Swat ATM (Machine (Machine))

Crash Course in Java

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

5 Arrays and Pointers

6.088 Intro to C/C++ Day 4: Object-oriented programming in C++ Eunsuk Kang and Jean Yang

Polymorphism. Problems with switch statement. Solution - use virtual functions (polymorphism) Polymorphism

recursion, O(n), linked lists 6/14

Cryptography and Network Security Prof. D. Mukhopadhyay Department of Computer Science and Engineering

CS 2112 Spring Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions

Transcription:

CS 33 Intro Computer Systems Doeppner Lab 08 - malloc and Friends Due: November 13, 2016 1 Introduction 1.1 C and Memory Roughly speaking, data in C can be stored in 4 different regions of memory: the bss 1, the data section, the stack, and the heap. 1.1.1 BSS/Data The bss and data sections are used to store various pieces of static data, such as global variables, fixed string and array constants, and local variables declared with the static keyword. Uninitialized variables are stored in the bss and initialized to 0, while statically initialized variables are stored in the data section. The size of these regions is determined at static link time and cannot be changed while the program is running. 1.1.2 Stack The stack is the region of program memory used to store data local to a function, including nonstatic local variables, arrays, and program arguments. Each time a function is called, the program allocates space on the stack known as a stack frame to store these variables. When the function returns, the stack frame is popped off the stack, freeing the space for future use. 1.1.3 Heap The heap 2 is a region of memory that can be used to store large blocks of data. The program can request memory in this region using a special set of functions, described below, through a process known as dynamic allocation. Blocks allocated on the heap must be explicitly freed when they are no longer needed. In this lab, you will use the heap and dynamic memory allocation to implement a linked list. 1.2 Dynamic Memory Allocation in C Up to this point in the course, your C programs have only used local and global variables (including arrays and structures) to store program information. Non-static local variables are stored within a given function s stack frame (or, in some cases, in registers). This is nice because the space used 1 The term bss, an acronym for Block Started by Symbol, originates from a pseudo-operation in UA-SAP, an assembler written in the 1950s for the IBM 704. 2 This is not the same as the min-heap data structure used in a priority queue. You should think of the heap as an unordered pool of memory, in contrast to the ordered stack. The origin of this usage of heap is unknown.

to store the variables is automatically created when the function is called, and discarded when the function returns. However, stack variables have several limitations: Memory used for stack variables is only valid over the lifetime of a function call. This means that pointers to local variables or arrays should not be returned from a function, because the variable referred to will be popped off the stack when the function returns, rendering the pointer invalid. The stack has a fixed maximum size, so storing too much data on the stack can cause a stack overflow. This can corrupt other parts of the program s memory or produce a segmentation fault. (The heap also has a maximum size, but it is much larger.) Prior to the C99 standard, the size of a local variable was required to be known at compile time so the compiler could know how much space to allocate on the stack. In particular, this meant that arrays had to have a fixed size. If you did not know in advance how much memory your program would require, this could present an obstacle. With C99, array size may be determined at runtime, but arrays on the stack still cannot be resized after they are created. The solution to the above problems lies in the malloc(), calloc(), realloc(), and free() functions, defined in <stdlib.h>. This group of functions provides a way in which arbitrary-size blocks of memory may be requested by the program at runtime. Dynamically allocated memory is stored in the heap, not the stack, so it will persist until it is explicitly deallocated. 1.2.1 Malloc vs. Global Data Onesmallthingtonotebeforethedetailsofmallocarediscussedishowthisdiffersfromglobaldata. Global data is great when it is known what information is needed to be shared by the program. If there is to be a shared data structure, it should be made into a global variable. However, in cases in which the size or even existence of the data can change throughout the program, dynamically allocated memory should be used. 1.2.2 Requesting a New Block of Memory void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); The malloc() and calloc() functions are used to request new blocks of memory on the heap. malloc() allocates a contiguous block of memory whose length in bytes is specified by the size parameter, and returns a pointer to the start of the block. calloc() takes two arguments, nmemb and size, and allocates space for an array of nmemb elements, each of which has size size. The function fills the requested memory with 0s before returning it. This is sometimes convenient, but is also slower. Both functions will return a null pointer on failure. Often, malloc() and calloc() are used in conjunction with the sizeof operator, which yields the number of bytes required for a given data type. For instance, to allocate an array of n integers on the heap, you could write: int *array = (int *) malloc(n * sizeof(int)); 2

or: int *array = (int *) calloc(n, sizeof(int)); Note that in either case, the returned pointer is of type void *, so it has to be cast to the desired type. 1.2.3 Resizing an Existing Block void *realloc(void *ptr, size_t size); To change the size of an existing block of memory, you use the realloc() function. realloc() resizes the given block of memory to the specified size and returns a pointer to the start of the resized block (which may or may not be the same as the old pointer). The contents of the memory block are preserved up to the minimum of the old and new sizes. If the new size is larger, the value of the newly allocated portion is indeterminate. If memory allocation fails, a null pointer is returned and the block specified by ptr is unaffected. 1.2.4 Deallocating a Block void free(void *ptr); The free() function will deallocate the entire block beginning at ptr, returning it to the heap for further memory allocation. If the given pointer is null, no action will be performed. The behavior of free() is undefined if the pointer does not point to the start of a dynamically-allocated block that has not yet been freed. Note that you do not have to specify the size of the block to be freed, as dynamically allocated blocks have metadata that includes this information. 1.2.5 Example The following example shows the combined use of malloc(), realloc(), and free(): void do_something(int n) { //Allocate space for an array of n integers int *array = (int *) malloc(n * sizeof(int)); //... //Double the size of the array array = (int *) realloc(array, 2 * n * sizeof(int)); //... //Free the array free(array); 3

1.2.6 Things to Avoid Dynamic memory management gives you great power. These functions give you the ability to allocate memory in a function that can be used far beyond the lifetime of the function call. They enable you to create large data structures that change size as necessary according to runtime conditions. But with great power comes great responsibility. Dynamic memory allocation requires careful discipline to avoid bugs and other problems. 1. Memory Leaks A memory leak is an issue that occurs when all pointers to a block of dynamically-allocated memory are lost before the block of memory is freed. Memory allocated on the heap persists beyond function calls and the computer has no way of knowing when a block of memory is not needed any more. In Java, this is handled by garbage collection 3, but there are no such niceties in C. The programmer must explicitly release a block of memory back into the heap using the free() command when it is done being used. The following code will cause a memory leak: /* Accept an array of dynamically-allocated strings, * and replace the string at a given index with a new one */ void replace_string(char **array, char *str, int index) { array[index] = str; //The pointer to the old value of array[index] is lost! Memory leaks can also occur when a data structure or array is freed without first freeing memory pointed to within the structure: struct foo { int x; char *str; void leakage() { struct foo *bar = malloc(sizeof(struct foo)); bar->x = 5; bar->str = (char *) malloc(2 * sizeof(char)); strncpy(bar->str, "!", 2); //... free(bar); //Careful! bar is freed but bar->str is not 3 A block of allocated memory with no pointers pointing to it cannot be accessed by the program, and is thus called garbage. Garbage collectors keep track of allocated memory and periodically clean up garbage during the execution of the program. This process is covered in Chapter 9 of the textbook. 4

Memory leaks may be difficult to detect because they do not directly affect the operation of the program. However, over time the leaked memory will build up. For long-running programs, this can eventually cause the program to run out of memory and fail. In general, each call to malloc() or calloc() should have a corresponding call to free() later on. 2. Misuse of free() Passing free() an invalid pointer, such as a pointer to an already-freed block of memory or a location other than the start of a dynamically allocated block, will cause unpredictable behavior. If you re lucky, you will immediately recieve an error and the program will terminate. In the worst case, you may experience data corruption, segmentation faulting, or other problems. The following example shows incorrect use of free(): void abuse_of_freedom() { int x = 3; free(&x); //Incorrect! x is stored on the stack, not the heap 3. Dangling Pointers A third type of mistake is attempting to read from or write to a block of memory that has already been freed. This can cause errors similar to those caused by returning a pointer to a local variable. The following is an example of this type of error in action: int dangling_pointage(int n, int x) { int *arr = (int *) malloc(a * sizeof(int)); //... free(arr); return arr[0]; //There is no guarantee on what the value of arr[0] will be The above code will compile successfully, but may cause unpredictable behavior at runtime. To avoid such errors, you should keep track of all pointers to a given dynamically-allocated block of memory and make sure they are never used after the block has been freed. If there is only one pointer to a given block, setting the pointer to NULL directly after calling free() can prevent accidental pointer misuse. 2 Assignment 2.1 Specification In this lab, your task is to use dynamic memory allocation to implement a basic singly-linked list in C. The linked list is represented by a series of nodes containing their value and a pointer to the next node. To complete this lab, you must fill in the implementations of the following functions: 5

LinkedList *linkedlist new(); function to instantiate a new linked list void linkedlist delete(); function to delete an entire linked list void linkedlist append(); function to add an element to the end of a linked list int linkedlist insert(); function to add an element before a specified index of a linked list int linkedlist remove(); function to remove the first occurence of an element from the linked list When created, the linked list is given three function pointers that will used be for various aspects of the linked list: An equals() function to compare two elements for equality, A copy() function to create a copy of an element for the linked list to store, and A delete() function to delete the linked list s private copy of an element. 2.2 Handout Your handout should contain the following files: linkedlist.h: A header file containing declarations of functions providing list functionality linkedlist.c: The C file where you will be implementing the list functions string fns.h, string fns.c: Files supporting various string operations tester.c: A C file providing a testing interface for the lab addme, addme2: Test data to use with the test interface Makefile: A makefile for the lab lab08.pdf: This handout You will only need to modify linkedlist.c to complete the lab. 2.3 Compiling and Running We have provided a makefile to allow you to easily compile this lab. To compile your code and the test code, run: make This will create an executable called tester that uses the linked list to store a collection of strings. The test program accepts the following commands: 6

a <str>: Appends <str> to the list i <str> <index>: Inserts <str> before the item located at <index> c <str>: Test if <str> is in the list r <str>: Remove <str> from the list x: Delete and re-instantiate the list s: Print the list size p: Print a representation of the list fa <file>: Append each whitespace-separated character string in file <file> to the linked list. For convenience, you are provided with test files addme and addme2 which contain 12 and 46 elements respectively. fr <file>: Remove each whitespace-separated character string in file <file> from the linkedlist. help: Print help information quit: Delete the set and exit the program To clear all compilation products, run: make clean 2.4 Testing To check for memory leaks and other types of memory errors, you can use the Valgrind utility. Valgrind reports issues such as accessing memory that has been freed or allocating memory without later freeing it. To run your program within Valgrind, enter the following at the command line: valgrind --leak-check=full your_executable where your executable is the file path of the executable to run (for example,./tester). 3 Future Expectations Now that you know how to allocate and free dynamic memory, you are expected to do so properly in all future assignments. Your TAs may deduct points if we find memory leaks or other instances of resource mismanagement in your code. 7

4 Getting Checked Off Once you ve completed the lab and verified that you have no memory leaks, run 33lab checkoff lab08 to submit and check off your lab. You may run this command as many times as you like; we will use the most recent grade and handin time recorded by this program. Remember to read the course missive for information about course requirements and policies regarding labs and assignments. 8