<<

Reading Assignment Structures and Unions

A structure is a mechanism that allows several data items of arbitrary types to be treated as a single entity.

K.N. King Chapter 16, 18 Structures are typically used when some block of logically related informantion needs to be processed in a program. Examples: name, address, telephone number X coordinate, Y coordinate, Z coordinate student name, student number, assignment marks

A union is a mechanism for saving space when several mutually exclusive data items need to be stored.

Good Style: always use a to create a single point of definition for any structure or union that has a significant use in a program.

216 217

Structure Declaration Structure Declaration Examples struct structureTag ¢ /* Type declarations */ structureFields struct A ¢ identifierList ; B £ int B , ; D X double X , Y ; Y AC

The structureTag provides a name for the structure. This name can be used char C ; nextA like a type name to declare variables of the structure type. struct A * nextA ; ;

The optional identifierList is a list of structure variables that are being £ declared at the same time as the structure. typedef struct AmyA;

The structureFields are ordinary data declarations that describe data /* Variable declarations */ contained in the structure. struct AS1, S2 ; S1 Example: struct exStruct typedef struct ¤ ¤ struct ¢ char name[ 25 ] ; char label[ 33 ] ; int J , K ; int price ; float ; S3 ; J £ K computer1, computer2 ; myStruct ; S2 ¥ ¥ myA S4 ; struct exStruct computer3 ; myStruct s1, s2 ;

S3 218 219

S4 HOW TO Use Structures To access a field in a structure variable, use the field access operator . computer1.price = 2199 ;

Each structure body represents a new scope. Declare the variables that you

want to treat as a unit in this scope. If P is a pointer variable that has been declared as a pointer to some structure type S, then (assuming P points at a structure) the fields of the structure can

Structure variables can be initialized with declaration by giving a list of values be accessed using the pointer operator -> for the structure fields. struct compStruct compPtr = & computer2 ; struct compStruct ¢ compPtr -> price = 3799 ; char name[ NAME LEN+1];

int price; the fields in a structure can be any C type-name including arrays and computer1 = ”IBM”, 3499 , computer2 = ”Dell”, 2265 ; structures. If a structure has a structure tag, a pointer to the structure can be £ ¢ £ ¢ £ declared inside the structure.

The assignment operator applies to entire structures.

The contents of the structure on the right side of the = is copied to the The size of a structure is approximately the sum of the sizes of the fields in structure on the left side. the structure. Use to get the exact size of any structure. computer2 = computer1 ;

Entire structures can not be compared.

220 221

HOW TO Use Structures Union Types The primary use of structures is to package several related variables together so that they can be treated as a single object. union unionTag ¢ fieldAlternativesList Structures can be used as function arguments anda function can return a identifierList ; structure as its value. £ WARNING: Structures are copied when they are passed by value or returned. Excessive copying of large structures can make a program inefficient.

unionTag is the name of the Consider using a pointer to the structure instead.

The fieldAlternativesList is a list of mutually exclusive fieldAlternatives.

Any type of object can be used as a field of a structure including another Each fieldAlternatives is a single data declaration. structure. Use a structure to pack several data items into one alternative. Examples: struct A struct B ¤ ¤

float X , Y ; struct ABownA; The optional identifierList is a list of union variables that are being declared at the same time as the union. int K ; int K ; ; myA Array[ 10 ] ; ¥ typedef struct AmyA; ; ¥

222 223 Union Declaration Examples

/* Type declarations */ /* Type declarations */ HOW TO Use Unions

union A union typeOverlay ¢ ¢ Unions are a mechanism for saving space when several mutually exclusive int B , C ; int integer ; alternative sets of data need to be stored and treated like a single object. double X , Y ; float floater ;

The fieldAlternatives overlap in memory so only one is active at any instant in char C ; unsigned char [ 4 ] ; time. struct A * nextA ; void * pointer ;

; ; The size of a union is approximately the size of the largest field alternative in £ £ typedef union AmyUA; the union. Use sizeof to get the exact size of a union.

C does NO run-time checking for proper use of unions

The programmer must provide some way of indicating which field alternative is active at any instant in time

224 225

Example of a self-identifying structure/union. Reading Assignment typedef enum point , square , circle , triangle ¤ ¥ uType ; struct uStruct uKind ¤ K.N. King Sections 17.1, 17.3, 17.4 uType unionKind ; Xcoordinate

side value union radiusYcoordinatesideA ¤ sideC sideB double side ; /* square */ int radius ; /* circle */ float sideA , sideB , sideC ; /* triangle */ value ; ¥ double Xcoordinate , Ycoodinate ; ; ¥

226 227 Dynamic Storage Allocation Dynamic Storage Allocation

Dynamic storage allocation is a mechanism that allows the programmer to Storage can be allocated for any type of data (i.e any type-name ). create new storage for data during the execution of a program

Pointers are used to access dynamically allocated storage.

Dynamic storage allocation is used to build complicated data structures like

Storage must be allocated and deallocated under programmer control lists, trees, and graphs whose size and shape is determined during program

execution Items in storage can be linked together with pointers in arbitrary ways

Items are accessed using pointers, any item not pointed to by some pointer is Think of using dynamic storage allocation for problems where you have to deal with arbitrarily large amounts of data or where the structure of the data permanently inaccessible isn’t known before program execution

Use of dynamic storage allocation is an important programming technique because it frees the programmer from the restrictions imposed by statically sized data structures.

228 229

Storage Allocation Functions malloc doesn’t initialize memory but calloc does initializes the memory by setting all to 0.

#include ¦ stdlib.h §

void *malloc( size tsize) When it is not possible to locate a block of memory large enough, the storage void *calloc( size t nobj , size tsize) allocation functions return NULL. void *realloc( void *p,size tsize) WARNING: Always check if the return value is NULL. p = (char *) malloc(n+1); if (p == NULL) ...

malloc allocates size bytes of storage and returns a pointer to the storage. calloc allocates storage for an array of nobj elements where each element WARNING: Be sure that a pointer passed to realloc came from previous call requires size bytes of storage of malloc, calloc, or realloc

realloc changes (smaller or larger) the size of the block of storage pointed to WARNING: realloc may move the data being reallocated to a different part of by p to be size bytes. Returns a pointer to the new storage. Copies old block memory. This will invalidate all existing pointers to that data. The ONLY of storage to new block of storage up to min( oldSize, newSize) pointer you can trust is the one returned by malloc.

Since malloc et.al. return a value of type void * you should use a type cast to Good Technique: Use the sizeof operator to get the correct size for the convert the type of the pointer returned to what you need. storage that you are allocating.

230 231 Deallocating Storage HOW TO Use Storage Allocation

void free( void *p) Always use sizeof to calculate the amount of storage reqested from the storage allocation functions. It is the only way to always get the correct size.

Never pass any pointer to free that wasn’t obtained directly from one of the free releases the storage block pointed to by p. storage allocation functions. CHAOS will ensue if you get this wrong. That storage must have been allocated using malloc, calloc or realloc or

Safe Storage Allocation CHAOS will ensue. #define MALLOC( size, type , pointer ) \ Dangling pointers are pointers that point to storage elements that have void * mTemp ; \ ¢ already been freed mTemp = malloc( (size) ) ; \ assert (mTemp!= NULL ) ; \ It is a logic error in your program if you try to use a dangling pointer

pointer = ( type ) mTemp ; \ £

Example double * Dptr ; MALLOC( 250 *sizeof( double ),double * ,Dptr)

232 233

Storage Allocation Examples NULL Pointer Dereferencing int * A ;

int nWords = 100 ; It is an ERROR to apply the pointer dereferencing operator ( * ) to any pointer that has the value NULL. A=(int * ) malloc(nWords * sizeof ( int )); The following property should hold for correct programs.

At every point where a pointer variable is dereferenced, the pointer typedef struct ¢ variable does not have the value NULL int X , Y ; If you cannot make an informal argument that this property holds at every Point ; £ pointer dereference than you have an ERROR in your program. typedef struct Point * PointPtr ;

WARNING: The NULL pointer is lurking everywhere waiting to cause #define PointArraySize ( 360 ) your program to crash PointPtr P ; P = ( PointPtr ) calloc( PointArraySize , sizeof ( Point ) ) ; P[100] -> X=10; P[100] -> Y=20;

234 235 Dangling Pointer Example

Dangling Pointers typedef struct ¢

A dangling pointer is a pointer that points at some block of storage that has float X ; been freed. ... It is an ERROR to use a dangling pointer since it points to GARBAGE. The bigStruct ; following property should hold for correct programs. £ typedef struct bigStruct * bigPtr ; At every point where a pointer variable is dereferenced, the pointer bigPtr P, Q ; variable can not be a dangling pointer. P = ( bigPtr ) malloc( sizeof ( bigStruct ) ) ; If you cannot make an informal argument that this property holds at every pointer dereference than you have an ERROR in your program. ... Q=P; ... free( P ) ; ... /* Q is a dangling pointer */

Q -> X = 25.7 ; /* ERROR */ 236 237

Memory Leaks List Data Structures

A program has a memory leak if it allocates storage that is never freed.

DataData Data Data Data

Memory leaks are not an issue for short lived programs (e.g. programming assignments) that do something and then stop. the operating system cleans

¡ A list is a sequence of nodes that are chained together using pointers. up memory when a program ceases execution.

¡ By convention the pointer value NULL is used to mark the end of a list.

Memory leaks are an issue for long running programs like operating systems,

¡ Lists allow you to deal with arbitrary amounts of data web browsers, word processors, and X window systems because the leaks

cause the program to grow slowly over time until it becomes to large to ¡ List processing algorithms are designed to processes lists from beginning to end. continue running. Random access to items in a list requires searching which can be very inefficient.

¡ Recursive functions are often the best way to design list processing algorithms. IF you are writing a long lived program you should take care to avoid memory

leaks. This is hard, it takes a lot of really careful memory management. ¡ List items are called nodes, cells, or elements. The explicit data that specifies “next” are called pointers or links.

¡ A Pointer variable which contains a pointer value to the first node on a list is called header

238 239 Singly Declarations Types of Lists

Singly linked lists A sequence of nodes linked by a single pointer. /* singly linked lists */

typedef struct listNode * ListPtr ; DataData Data Data Data struct listNode ¢

Singly linked list with header A singly linked list that is accessed via a header /* Declare Data Here */ block that contains pointers to the first and last node in the list. int value ; /* list of integers */ listPtr next ; /* link to next node */ Data Data Data Data Data ; £ typedef struct listNode LISTNODE ;

Doubly linked list A sequence of nodes where each node contains a pointer to the next node in the list and a pointer to the previous node in the list #define LISTNODESIZE ( sizeof( LISTNODE ) )

Data Data Data Data

240 241