9

feastcanadianSoftware and s/w Development

Dec 14, 2013 (3 years and 6 months ago)

67 views

User
-
defined Types

and

Memory Management

User
-
defined Types


C allows for the creation of custom data types.


Custom data types allow you to build more
complex data types for supporting more
sophisticated programs.


C provides several constructs


structures *


enumerations *


bit
-
fields


unions

*Topics covered in N305

User
-
defined Types


Structures


A structure is a collection of related elements,
possibly of different types with a single name
(similar to an array but also very different).


Structures serve as templates that define a data
type.


Structures are defined using the keyword
struct.


C's closest structure to an object.

User
-
defined Types


Three ways to declare/define a structure.


variable structures (unusual)

struct {field
-
list} structure_variable;



tagged structures

struct tag {field
-
list} structure_variable;



type
-
defined structures

typedef struct {field
-
list} type_name;



User
-
defined Types


Structure variable


struct

{


char id[10];


char name[26];


int gradePoints;

} student;


gets(student.id);

gets(student.name);

student.gradePoints=5;

In this example, the field list contains

three elements… two character arrays

and an integer
.

In this example, there is only one

variable of this type declared. You may


use more.

Use a period (dot operator..very

high precedence) to access the elements

of a structure.

User
-
defined Types


Tagged structures

struct student


{


char id[10];


char name[26];


int gradePoints;

} ;


struct student aStudent;


gets(aStudent.id);

gets(aStudent.name);

aStudent.gradePoints=5;



A tag defines the name associated

with the structure. Use this tag to

declare a variable of this type.

You may define a variable list after the

closing brace, but it is not recommended.


Structures are best placed in global area

of the program (or header file). Keep the

variables local.

User
-
defined Types


Type
-
defined structures

typedef struct

{


char id[10];


char name[26];


int gradePoints;

}STUDENT;


STUDENT aStudent;


gets(aStudent.id);

gets(aStudent.name);

aStudent.gradePoints=5;

Use the
typedef

keyword to explicitly

define a new data type (sort of). It

really just creates a new name for a

derived type. Commonly used with

structures.

The convention is to use all caps for

the new data type.

User
-
defined Types


Arrays of structures


Arrays of structures can be created just like any
other array type.


Access an element by placing the subscript after
the structure name.


STUDENT aStudent[NUMSTUDENTS];


for(i=0;i<NUMSTUDENTS;i++)


{



gets(aStudent[i].id);


}


User
-
defined Types


Passing structures to functions


Passing single elements: Treat like any other
variable.


foo(aStudent.gradePoints);

foo(&aStudent.gradePoints);

foo(aStudent[1].gradePoints);

foo(aStudent.id);

User
-
defined Types


Passing structures to functions


Passing the entire structure:

#include <stdio.h>

typedef struct

//define structure before any reference

{


char id[10];


char name[26];


int gradePoints;

}STUDENT;

void foo(STUDENT aStudent2);


//prototype


void main(void)

{



STUDENT aStudent;



gets(aStudent.id);



foo(aStudent);

}

void foo(STUDENT aStudent2)

{



printf("%s
\
n",aStudent2.id);

}

#include <stdio.h>

struct student

{


char id[10];


char name[26];


int gradePoints;

};

void foo(struct student aStudent2);


void main(void)

{


struct student aStudent;


gets(aStudent.id);


foo(aStudent);

}

void foo(struct student aStudent2)

{


printf("%s
\
n",aStudent2.id);

}

User
-
defined Types


Structure Pointers


void foo(struct student aStudent2)

{


struct student *ptr=&aStudent2;


printf("%s
\
n",(*ptr).id);


printf("%s
\
n",ptr
-
>id); //preferred method

}

User
-
defined Types


Structures


A data “template” that is used to create custom types.


Built from other C types.


Variables declared with, or separate from structure
definition.


Referenced with dot operator.


May only be used with assignment operator when
accessing the structure entity as a whole.


May be used with arrays, passed to functions, used with
pointers


Structures may be nested and may contain arrays.



User
-
defined Types


enumerations


A set of integer constants that specify all legal values a variable of
that type may have.


enum tag{list} variable list;


enum coins

{



penny,


//Zero if not specified



nickel,



dime,



quarter,



half_dollar,



dollar

};

enum coins money;

User
-
defined Types


enumerations


All enumeration symbols are integers and must
be treated as such.


Unless otherwise denoted, the enumeration
symbols start with a value of 0 and increase by 1
for each symbol in the list.


enum coins money;


money=quarter;


printf("%d
\
n",money);

Memory Allocation Functions


Static memory allocation


To this point, we have written source code that
requires the declaration and definition of memory
be specified in the program. The number of bytes
reserved cannot be changed during run
-
time.


Dynamic memory allocation


Uses predefined functions to allocate and release
memory (from the heap) for data during run
-
time.


Four functions: malloc(), calloc(), realloc(), and
free() from stdlib.h

Memory Allocation Functions


malloc()


The malloc() function allocates a block of memory that
contains the number of bytes specified in its parameter. It
returns a void pointer to the first byte of allocated
memory or a NULL pointer if unsuccessful.


void *malloc (size_t size);


(size_t is usually an unsigned integer)



The allocated memory is not initialized, so you don’t
know what it contains.

Memory Allocation Functions


malloc()


Use sizeof() function to specify number of bytes allocated
by malloc().


int *ptrInt;

ptrInt=malloc(sizeof(int)); //may have to cast pointer



If there is not enough memory left in the heap, then
problems will occur (strange results or the program may
crash). Your program must check for memory overflow.


Also, never call malloc() with a zero size.

Memory Allocation Functions


malloc()


char *ptr;

if(!(ptr=(char*)malloc(80*sizeof(char))))

{


puts("Out of memory!");


exit(1);

}

Pointer variable p gets the address

of the first byte of memory in the block

(80 bytes in this example) grabbed

by malloc.

Pointer returned by malloc has been

cast as a character to prevent compile

error. (This is not required by ANSI C

but some compilers (book) need it.)

Memory Allocation Functions


free()


Used to release memory obtained with memory
allocation functions.


void free(void *ptr);



NEVER call free with an invalid argument (will destroy
free list).


Make sure memory allocated with malloc and calloc is
freed when no longer required by the program.


free(ptr);

Memory Allocation Functions


calloc()


Primarily used to allocate memory for arrays.


Differs from malloc:


1. Allocates a contiguous block of memory large
enough to contain an array of elements of the
specified size. Requires two parameters.


2. Returns a pointer to the first element of the
allocated array.


3. Initializes memory to zero or NULL.


void *calloc(size_t elements, size_t size);


Memory Allocation Functions


calloc()


To allocate memory for an array of 10
integers:


int *ptr;


if(!(ptr=(int*)calloc(10,sizeof(int))))


{



puts("Out of memory!");



exit(1);


}

Memory Allocation Functions


Creating a dynamic array.


int *BuildArray(int numElements)

{


int *newArray;


//pointer to block of memory



if(!(newArray=(int*)calloc(numElements,sizeof(int))))


{



puts("Out of memory!");



exit(1);


}


return newArray;

}


To call this function use:

int *myArray;

myArray=BuildArray(arrayLength); //Array length is an integer variable.

This function will return a pointer

to an integer.