Arrays & Dynamic Memory Allocation

Slides:



Advertisements
Similar presentations
Linked Lists CSE 2451 Matt Boggus. Dynamic memory reminder Allocate memory during run-time malloc() and calloc() – return a void pointer to memory or.
Advertisements

Pointers in C Rohit Khokher
CS1061: C Programming Lecture 21: Dynamic Memory Allocation and Variations on struct A. O’Riordan, 2004, 2007 updated.
ECE Application Programming Instructor: Dr. Michael Geiger Fall 2012 Lecture 31: Dynamic memory allocation.
Programming in C Pointers and Arrays, malloc( ). 7/28/092 Dynamic memory In Java, objects are created on the heap using reference variables and the new.
CSCI 171 Presentation 11 Pointers. Pointer Basics.
Agenda  Review: pointer & array  Relationship between pointer & array  Dynamic memory allocation.
Pointer applications. Arrays and pointers Name of an array is a pointer constant to the first element whose value cannot be changed Address and name refer.
Memory allocation CSE 2451 Matt Boggus. sizeof The sizeof unary operator will return the number of bytes reserved for a variable or data type. Determine:
Programming III SPRING 2015 School of Computer and Information Sciences Francisco R. Ortega, Ph.D. McKnight Fellow and GAANN Fellow LECTURE #5 More about.
1 Pointers A pointer variable holds an address We may add or subtract an integer to get a different address. Adding an integer k to a pointer p with base.
Memory Arrangement Memory is arrange in a sequence of addressable units (usually bytes) –sizeof( ) return the number of units it takes to store a type.
1 Chapter 9 Arrays and Pointers. 2  One-dimensional arrays  The Relationship between Arrays and Pointers  Pointer Arithmetic and Element Size  Passing.
1 Pointers, Dynamic Data, and Reference Types Review on Pointers Reference Variables Dynamic Memory Allocation –The new operator –The delete operator –Dynamic.
Pointers Applications
17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.
1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation.
Computer Science and Software Engineering University of Wisconsin - Platteville 2. Pointer Yan Shi CS/SE2630 Lecture Notes.
ECE 103 Engineering Programming Chapter 47 Dynamic Memory Alocation Herbert G. Mayer, PSU CS Status 6/4/2014 Initial content copied verbatim from ECE 103.
C Programming Day 4. 2 Copyright © 2005, Infosys Technologies Ltd ER/CORP/CRS/LA07/003 Version No. 1.0 More on Pointers Constant Pointers Two ways to.
Prachi A. Joshi Assistant Professor in CSE DIEMS,Aurangabad Unit 1 : Basic Concepts Pointers and dynamic memory allocation, Algorithm Specification, Data.
Pointers in C Computer Organization I 1 August 2009 © McQuain, Feng & Ribbens Memory and Addresses Memory is just a sequence of byte-sized.
ECE Application Programming
Introduction to Computer Organization & Systems Topics: C arrays C pointers COMP Spring 2014 C Part IV.
+ Dynamic memory allocation. + Introduction We often face situations in programming where the data is dynamics in nature. Consider a list of customers.
ECE Application Programming Instructors: Dr. Michael Geiger & Nasibeh Nasiri Fall 2015 Lecture 31: Structures (cont.) Dynamic memory allocation.
MORE POINTERS Plus: Memory Allocation Heap versus Stack.
BIL 104E Introduction to Scientific and Engineering Computing Lecture 9.
DYNAMIC MEMORY ALLOCATION. Disadvantages of ARRAYS MEMORY ALLOCATION OF ARRAY IS STATIC: Less resource utilization. For example: If the maximum elements.
Arrays and Pointers (part 1) CSE 2031 Fall July 2016.
CSE 220 – C Programming malloc, calloc, realloc.
Dynamic Allocation in C
Insertion sort Loop invariants Dynamic memory
Pointers and Dynamic Arrays
Stack and Heap Memory Stack resident variables include:
Winter 2009 Tutorial #6 Arrays Part 2, Structures, Debugger
Dynamic Allocation Review Structure and list processing
Linked List :: Basic Concepts
ECE Application Programming
5.13 Recursion Recursive functions Functions that call themselves
Lectures linked lists Chapter 6 of textbook
ECE Application Programming
C Programming Language Review and Dissection IV
Module 2 Arrays and strings – example programs.
Programming Languages and Paradigms
Lecture 6 C++ Programming
Prof. Neary Adapted from slides by Dr. Katherine Gibson
Object Oriented Programming COP3330 / CGS5409
Programming and Data Structures
Pointers, Dynamic Data, and Reference Types
CSC215 Lecture Memory Management.
Dynamic Memory Allocation
CS111 Computer Programming
Memory Allocation CS 217.
EECE.2160 ECE Application Programming
Outline Defining and using Pointers Operations on pointers
Dynamic Memory Allocation (and Multi-Dimensional Arrays)
Linked List.
Dynamic Allocation in C
Pointers and Arrays Beyond Chapter 16
Linked Lists Adapted from Dr. Mary Eberlein, UT Austin.
EECE.2160 ECE Application Programming
EECE.2160 ECE Application Programming
TUTORIAL 7 CS 137 F18 October 30th.
CS31 Discussion 1H Fall18: week 6
Dynamic Memory – A Review
Pointers, Dynamic Data, and Reference Types
EECE.2160 ECE Application Programming
EECE.2160 ECE Application Programming
Module 13 Dynamic Memory.
Presentation transcript:

Arrays & Dynamic Memory Allocation 2D arrays malloc, calloc, realloc, and free Linked Lists Pointers to pointers

2D Arrays Used for tables, matrices Specify number of rows, columns 0-indexing for rows and columns an array of 1D arrays Examples: int matrix[10][5]; // 5 rows, 10 cols char conversionTable[26][26]; Initializer lists: specify bracketed lists for each row, or omit row brackets – values will fill array row by row int arr[3][4] = {{0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11}}; int arr[3][4] = {0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; If initializer list is too short to fill all elements, rest are filled with 0

2D Array Example int main() { // 4 rows, 2 columns int arr[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}}; // print array for(int i = 0; i < 4; i++) { for(int j = 0; j < 2; j++) { printf("%d\t", arr[i][j]); } printf("\n"); Output: 1 2 3 4 5 6 7 8

2D Array Example In a 2D array, you can omit the number of rows if the array is completely initialized when declared If a parameter is a 2D array, the number of rows may be omitted: int sum2D(int arr[][LEN], int n) { int sum = 0; for(int i = 0; i < n; i++) { for(int j = 0; j < LEN; j++) { sum += arr[i][j]; } return sum;

Variable Length Array Parameter Starting in C99: specify array dimension with non-constant int sumArray(int n, int a[n]) {// must put n first ...} int sum2DArray(int n, int m, int a[n][m]) { int sum = 0; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { sum += a[i][j]; } return sum; n, m must come before a in parm list

Pointers & 2DArrays Arrays stored in row-major order To initialize elements in 2D array: nested for loops single loop another option with pointer arithmetic: int arr[NUM_ROWS][NUM_COLS]; int *p; for(p = &a[0][0]; p <= &arr[NUM_ROWS-1][NUM_COLS-1]; p++) { *p = 3; } No real advantage of second approach – less readable Use a pointer to a row to process that row: p = &arr[i][0]; // for valid row number i. OR p = arr[i]; // p points to row i

Example int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int *p; for(int i = 0; i < 3; i++) { p = &arr[i][0]; for(int j = 0; j < 3; j++) printf("%d ", *(p+j)); printf("\n"); } Output: 1 2 3 4 5 6 7 8 9 for(int i = 0; i < 3; i++) { p = arr[i]; for(int j = 0; j < 3; j++) printf("%d ", *(p+j)); printf("\n"); }

Row Processing: 2D Array So arr[i] is address of row i in 2D array arr Can pass arr[i] to function that takes 1D array as argument To set all values of row i to zero: int arr[NUM_ROWS][NUM_COLS], *p, i; … for (p = arr[i]; p < arr[i] + NUM_COLS; p++) *p = 0;

2D Array Name as Pointer Any array name can be used as a pointer arr is a pointer to arr[0] arr is regarded as a 1D array with elements that are 1D arrays arr has type int (*) [NUM_COLS] To set elements in column c to zero: for(p = arr; p < arr + NUM_ROWS; p++) { (*p)[c] = 0; } Since p points to a row of arr, incrementing p assigns p to point to next row

Dynamic Memory

Dynamic Memory We can allocate memory on the heap during program execution Often used for strings, arrays, structs, linked lists, trees <stdlib.h> declares 3 memory allocation functions: malloc: allocates an uninitialized block of memory calloc: allocates a block of memory and initializes to zero Takes time to zero out memory – don't use unless needed realloc: resizes allocated block of memory All three return type void * (a void pointer) Return null pointer if block of requested size isn't found NULL represents null pointer

Allocating Memory prototype: void *malloc(size_t size); malloc allocates contiguous size bytes and returns pointer to it size_t: unsigned integer type (defined in <stdlib.h>) void free(void *ptr); // free memory when done with it Example: array of n ints int * a = malloc(n * sizeof(int));// a holds address of first elt if(a != NULL) { // better: if(a) for(int i = 0; i < n; i++) a[i] = i; // Or: *(a+i) = i; } Later - free memory: free(a);

Deallocation & Common Mistakes free(a); // releases allocated block on heap Free memory which has been dynamically allocated Calling free() does not change value of pointer variable – reset it to NULL Common mistakes: dangling pointer: a pointer that contains the address of dynamic memory which has been freed Can happen when there are multiple pointers to dynamically allocated memory memory leak: memory is allocated and not freed up again system will eventually run out of memory can occur if memory is malloc'ed in a loop check return value of malloc/calloc/realloc to ensure it isn't NULL use valgrind to detect (more on valgrind in recitation) double deallocation: attempting to deallocate memory pointed to by dangling pointer uninitialized pointer: an uninitialized pointer contains garbage – trying to access random memory location can cause unpredictable behavior

Memory Leak p = malloc(...); q = malloc(...); p = q; no pointer to 1st block (garbage) Block cannot be freed This sort of code leads to memory leaks

Dangling Pointer char *ptr1 = malloc(10*sizeof(char)); // new string char *ptr2 = ptr1; ... free(ptr2); strcpy(ptr1, "hello"); Two dangling pointers – point to same deallocated memory

String Functions char *myConcat(const char *s1, const char *s2) { char *result = malloc(strlen(s1) + strlen(s2) + 1); if(result == NULL) { printf("Error: malloc failed\n"); exit(EXIT_FAILURE); } strcpy(result, s1); strcat(result, s2); return result; Function call: char *p = myConcat("hello ", "world"); process termination: flushes output streams, closes open streams Type man 3 exit at command prompt for more info version of strcat: takes pointers to two strings, allocates enough memory for both + the null character, allocates memory for concatenated string and copies both strings in

calloc Prototype: void *calloc(size_t nmemb, size_t size); Allocates space for nmemb elements, each of size bytes Initializes memory to 0 Performance hit for initialization – don't use unless you really need initialization to 0

Dynamically Allocated Arrays Particularly useful before C99 standard allowed non-constant array sizes int numVals = -1; double *data = NULL; do { printf("How many data values do you want to store? "); scanf("%d", &numVals); } while (numVals < 1); data = malloc(numVals * sizeof(double)); // uninitialized // data = calloc(numValues, sizeof(double)); // cleared to zeros if(!data) printf("Error – malloc failed\n");

realloc Resize a dynamically allocated array Prototype: void *realloc(void *ptr, size_t size); ptr points to previously allocated memory block if ptr is NULL, new block allocated and pointer to block returned size = new size of block in bytes (can be larger or smaller than original size) if size is 0 and ptr points to existing block, block is deallocated and NULL is returned Returns pointer to new block or NULL on failure Attempts to use original block of memory, shrinking or expanding it in place int *temp = realloc(ptr, 1000 * sizeof(int)); if(temp) ptr = temp; Check for success of realloc call before resetting pointer to data

Linked List chain of structs (nodes) in which each node contains a pointer to next node last node contains null pointer Need pointer to head of list (1st element) Advantages over array: easy to increase size of list easy to insert or delete element at any location Disadvantages: Slow access to ith element of list

Define List Node Nodes contain data and pointer to next node in list struct node { int value; struct node *next; }; node must be tag, not typedef alias, to allow declaration of type of next pointer

Create Empty List Sets list pointer to null, creating empty list struct node *first = NULL;

Exercise Add first node to list – value for node is 10 allocate memory for new node initialize node's fields update list pointer

Exercise Write code that adds a new element to the beginning of a list. Assume first is a pointer to the beginning of the list, and add 15 to the list.

Create List Node List nodes are typically allocated dynamically and added to list Allocate memory for node Store data in node Insert node into list Allocating memory: struct node *new_node = malloc(sizeof(struct node)); Store data in node: new_node  value = 10; OR: (*new_node).value = 10; OR: scanf("%d", &new_node  value);

Insert Node at Beginning of List new_node points to node we are inserting first always points to first node in list here list was initially empty new_node  next = first; first = new_node;

Insert Node at Beginning of List new_node points to node we are inserting first points to first node in list new_node = malloc(sizeof(struct node)); new_node  value = 20; new_node  next = first; first = new_node;

Function: Insert Node at Beginning of List struct node *addToList(struct node *list, int n) { struct node *newNode = malloc(sizeof(struct node)); if(newNode == NULL) { printf("Error: malloc failed\n"); exit(EXIT_FAILURE); } newNode  value = n; newNode  next = list; return newNode; Store return value in first: first = addToList(first, 10); first = addToList(first, 20);

Exercise Write a function that finds integer n in list, and returns a pointer to the node that contains n. The function returns NULL if n is not in the list. struct node *searchList(struct node *list, int n) {

Search Linked List Look for node containing value n struct node *searchList(struct node *list, int n) { struct node *p; for(p = list; p != NULL; p = p  next) if(p  value == n) return p; return NULL; } Could also just use list to iterate, since it's a copy of the original list pointer (we can't change it). for(; list != NULL; list = list  next) {if(list value == n) return list; ...

Search Linked List loop body is empty struct node *searchList(struct node *list, int n) { for(; list!= NULL && listvalue != n; list = listnext) ; return list; } loop body is empty list is NULL if we reach end of list, so NULL is returned if n not found more natural to use while loop: while(list != NULL && listvalue != n) list = listnext;

Deleting Node From Linked List Easy to delete node from linked list 3 steps: Locate the node Maintain pointer to previous node (prev) and pointer to current node (cur) Initially prev is NULL, cur is first (list pointer) Update previous node's next pointer to bypass deleted node Free the deleted node

Deleting Node From List Assume list is as follows, n is 20 cur = list; prev = NULL; while(cur != NULL && curvalue !=n) prev = cur; cur = cur  next;

Deleting Node From List while(cur != NULL && curvalue !=n) prev = cur; cur = cur  next; loop terminates since curvalue != n is false

Deleting Node: Steps 2 & 3 Bypass Deleted Node and Free It prev  next = cur  next; free(cur);

Deleting Node From Linked List struct node *deleteNode(struct node *list, int n) { struct node *cur, *prev; for(cur = list, prev = NULL; cur != NULL && cur  value != n; prev = cur, cur = cur  next) ; if(cur == NULL) return list; // n not found if(prev == NULL) list = list  next; // n in first node else prev  next = cur next; // n in some other node free(cur); return list; } Return list pointer. Function returns FIRST node containing n. Deleting 1st node is a special case that requires updating the list pointer.

Exercise Write a function that returns the length of a linked list: int linkedLength(struct node *list) { // Your code here }

Ordered List Nodes are maintained in order – decreasing or increasing Inserting is more difficult than inserting always at the beginning of the list Exercise: Rewrite addToList assuming that the list of nodes is in increasing order.

Pointers to Pointers If we want a function to modify a pointer, we must pass a pointer to that pointer The function addToList adds a new element to beginning of a list, and updates the list pointer, rather than returning the list pointer void addToList(struct node **listRef, int n) { struct node *newNode = malloc(sizeof(struct node)); if(newNode == NULL) { printf("Error: malloc failed\n"); exit(EXIT_FAILURE); } // What goes here??

Pointers to Pointers: Add to Beginning of List void add_to_list(struct node **listRef, int n) { struct node *new_node;   new_node = malloc(sizeof(struct node)); if (new_node == NULL) { printf("Error: malloc failed in add_to_list\n"); exit(EXIT_FAILURE); } new_node->value = n; new_node->next = *listRef; *listRef = new_node; Call: addToList(&first, 10);

Exercise Write C code that adds a new node (containing your favorite integer) to the end of a linked list. Assume list points at the first element of the list. struct node *list = ... ;

Exercise Write a function that moves the last node in a list to the front of the linked list. headRef is a pointer to the list pointer. void moveLastToFirst(struct node **headRef) { ...

Exercise Write a function that reverses a linked list. headRef is a pointer to the list pointer. void reverse(struct node **headRef) {...