Title: G52CFJ CC for Java Programmers Lecture 6
1G52CFJ C/C for Java Programmers Lecture 6
- structs
- dynamic memory allocation
2Last lecture the stack
- Parameters are copied when passed into a function
- BUT A copy of a pointer still points to the same
thing - Local variables can be static or non-static
- You cannot have static local variables in Java
- Normal (non-static) local variables
- Exist for duration of the block they are in
- Are stored in stack frames
- Static local variables
- Remember their value across function calls
- Exist for the life-time of the program
- Only get initialised once (first time)
- Global variables
- Declared outside of all functions
- Exist for life-time of program (from at least
first usage) - Maintain their value
3Visibility is different from lifetime
- Just because a variable exists, doesnt mean that
you can access it - Globals access from anywhere
- May be shadowed by parameters or local variables
- In C (not C) you can use Scope Resolution to
access globals when they are shadowed - Can be hidden within a file (see lecture 10)
- Static local variables
- Only access from inside the function
- Exist all of the time, like globals
- Do not use a pointer to something, if the thing
it points to no longer exists
4This lecture
- Brief aside define
- structs
- How big is a variable (or type of variable)
- Allocating memory from the heap
- And freeing it again afterwards
- Including arrays
5define and the pre-processor
6define
- An intelligent find and replace facility
- Considered bad in C code (useful in C)
- e.g. define a constant
- define MAX_ENTRIES 100
- Replace occurrences of MAX_ENTRIES by the text
100 (without quotes) - if ( entry_num lt MAX_ENTRIES )
- Remember Done by the pre-processor!
- E.g. NOT actually a definition of a constant
- More on this in later lectures, and see zombies
example
7structs (mini-classes?)
8structs
- Group related data together
- Examples
- struct Time
- int hour int minute int second
-
- Group three integers together to specify a time.
- struct Date int d, m, y
- Shorter version, for day, month, year
- C structs and classes (introduced later) can be
considered to be extensions of C structs
struct.c
9Position of data
- Like arrays, the position of the members inside a
struct is known - Elements will be placed sequentially in memory in
the order they are defined in the structure
(sometimes this matters) - So you CAN use the ordering to determine where
parts will be in memory - You can ask for the sizeof() the previous fields
to work out the position of a later field
10Creating a struct on the stack
- Create objects of type struct using the name
- Need to say struct ltnamegt in C
- Example
- struct Date int d, m, y
- int main( int argc, char argv )
-
- struct Date dob 1, 4, 1990
- printf( DOB 02d/02d/04d\n,
- dob.d, dob.m, dob.y )
- dob.d 2
- return 0
struct.c
11Accessing members of a struct
- Use the . operator to access members
- Exactly as for Java classes
- Example
- struct Date int d, m, y
- int main( int argc, char argv )
-
- struct Date dob 1, 4, 1990
- printf( DOB 02d/02d/04d\n,
- dob.d, dob.m, dob.y )
- dob.d 2
- return 0
struct.c
Initialisation
Access values
12structs act like any other type
- Once defined, you can use structs as any other
type - For example
- You can take the address of a variable of type
struct and store it in a struct pointer - e.g. struct Date pDob dob
- You can embed a struct as a member of another
struct - You can create an array of structs
- You can ask for the sizeof() a struct
13Creating an initialised struct Date
struct Date char d, m short y struct
Date singleDate 1, 2, 2000 printf(
"Initialised singleDate is02d/02d/04d\n",
singleDate.d, singleDate.m, singleDate.y )
1) Define the type struct Date
2) Create and initialise a variable of type
struct Date
- Initialised singleDate is 01/02/2000
14Arrays of structs
struct Date dobs5
struct Date char d, m short y
dobs0
d
Notes Syntax is the same as for arrays of
basic types, e.g. int Elements are one
after another in memory (like other arrays)
m
y
dobs1
d
m
y
dobs2
d
struct Date
char d
m
char m
y
short y
dobs3
d
m
y
dobs4
d
m
y
15Array of structs (on the stack)
struct Date arrayOfDatesOnStack5 for ( i0
i lt 5 i ) printf( "arrayOfDatesOnStackd
is 02d/02d/04d\n", i, arrayOfDatesOnStack
i.d, arrayOfDatesOnStacki.m,
arrayOfDatesOnStacki.y )
Array of 5 elements
- arrayOfDatesOnStack0 is 00/00/0000
- arrayOfDatesOnStack1 is 02/00/0000
- arrayOfDatesOnStack2 is -104/-51/0034
- arrayOfDatesOnStack3 is -41/53/24833
- arrayOfDatesOnStack4 is -71/-74/24854
Values are uninitialised!!!
16Array of dates on the stack
/ Uses array initialiser and struct initialiser
/ struct Date initArrOfDatesOnStack
1,1,2001, 2,2,2002, 3,3,2003, 4,4,2004
, 5,5,2005 for ( i0 i lt 5 i
) printf( "initArrayOfDatesOnStackd is
02d/02d/04d\n", i, initArrayOfDatesOnStacki
.d, initArrayOfDatesOnStacki.m,
initArrayOfDatesOnStacki.y )
- initalisedArrayOfDatesOnStack0 is 01/01/2001
- initalisedArrayOfDatesOnStack1 is 02/02/2002
- initialisedArrayOfDatesOnStack2 is 03/03/2003
- initialisedArrayOfDatesOnStack3 is 04/04/2004
- initialisedArrayOfDatesOnStack4 is 05/05/2005
17Stack reminder
- These structs were created on the stack
- (i.e. as local variables)
- RememberData on the stack vanishes when the
stack frame that contains it is removed from
thestacki.e. when the function/block in which
it is defined ends
18Short-cut notation
19-gt for pointers to structs
- Assume that you have a pointer to a struct, pDob
- struct Date int d, m, y
- struct Date dob
- struct Date pdob dob
- Due to precedence rules, you need to put ()
brackets around the dereferencing - E.g. (pdob).y 2008
- There is a shortcut to access the members
- Short-cut uses the -gt instead of (ltptrgt).
- E.g. pdob-gty 2008
20struct vs struct
- struct time int hour, minute, second
- struct time t
- t.hour 12
- t.minute 34
- t.second 14
- struct time pt t
- pt-gthour 11
- pt-gtminute 13
- pt-gtsecond 5
- printf( "The time is 02d02d02d\n",
- t.hour, t.minute, t.second )
21Passing structs into functions
- struct Date dob 1, 4, 1990
- Either pass the struct
- A (bit-wise) copy of the struct is put on the
stack - Any changes made inside the function affect the
copy - void foo(struct Date dob) dob.m 3
- foo( dob )
- Or a pointer to the struct
- A copy of the pointer is put on the stack
- You can use the pointer to access the original
copy - void bar(struct Date pdob)pdob-gtm 3
- bar( dob )
For struct itself use .
For a pointer use -gt, or (pdob).m
22How big are my variables?
23How big is a variable? (sizeof)
- C/C provides the sizeof() operator
- It looks like a function but is actually an
operator! - Returns the size as a multiple of char size
- Examples of use
- int size_char sizeof(char) // e.g. 1
- int size_short sizeof(short) // e.g. 2
- int size_long sizeof(long) // e.g. 4
- Can also use sizeof() on
- struct (structures) and unions
- objects and classes (C only)
- pointers (the size of the pointer itself)
24Allocating memory from the heap
25Process structure in memory
Code (or text) segment The program code
- Data and BSS segment(s)
- Constants, string literals (?)
- Global variables, static local variables
Heap Data area that grows upwards towards
stack Specially allocated memory (malloc, free,
, probably new, delete)
Stack Data area that grows downwards towards the
heap LIFO data structure, for local variables and
parameters
26The heap
- A big store of memory
- You can ask for memory from it
- malloc(), calloc(), realloc() functions
- You can tell if that you no longer need memory it
has given to you - free() function
I need this many bytes of memory ltSizegt
HEAP
Use this address ltAddressgt
I no longer need this memory ltAddressgt
HEAP
27It gives you generic memory
- malloc() will allocate bytes of memory
- It will not (directly) allocate for you a string,
or an array, or an int (unlike Java/C new) - You need to convert the returned pointer to the
correct type - i.e. treat the memory as if it was that type
- malloc() returns a void
- In C (not C) implict conversion to/from void
- You should include ltstdlib.hgt to use these
functions
285 steps to dynamic memory bliss
- Step 1 Work out how much memory you need to
allocate - Remember the sizeof() operator!
- Step 2 Ask for that amount of memory
- Use malloc( memory_size )
- Step 3 Store the returned pointer e.g. in C
- int pInt malloc( sizeof(int) )
- C needs a cast, e.g. (int)malloc()
- Step 4 Use the memory through the pointer as if
it was the correct type - pInt 5 (pInt) pInt 12
- Step 5 When finished, free the memory
- free( pInt )
29Memory allocation functions
- The stdlib header file declares the functions
- include ltstdlib.hgt
- Each returns a void with the address of the
newly allocated memory - When you have finished with the memory, this
pointer should be passed to free() - If memory allocation functions fail, the
functions return NULL - There are three functions to know
- malloc(), calloc(), realloc()
30malloc, calloc and realloc
- void malloc(size_t sz)
- Allocate sz bytes of uninitialised memory
- void calloc(size_t count, size_t sz)
- Allocate memory for count elements of size sz
each - The memory is initialised to zeroes!!!
- void realloc(void old_pointer, size_t sz)
- old_pointer is a pointer from an existing
malloc() - If possible, grow or shrink the existing memory
allocation to be size sz bytes - If not, then allocate new memory for the new size
(sz bytes), copy the bytes of the existing memory
to the new address and free the old memory - If it fails (returns NULL) the old memory will be
unchanged
31Creating a struct on the heap (rather than stack)
32A struct Date on the heap (1)
malloc(sizeof(struct Date))
Allocate the memory
sizeof( struct Date )
33A struct Date on the heap (2)
struct Date heapDate malloc(sizeof(struct
Date))
Allocate the memory
Treat memory as a struct Date
d ?
heapDate
m ?
sizeof( struct Date )
y ?
34A struct Date on the heap (3)
struct Date heapDate malloc(sizeof(struct
Date)) heapDate-gtd 4 heapDate-gtm
10 heapDate-gty 3945 printf( "HeapDate
is 02d/02d/04d\n", heapDate-gtd,
heapDate-gtm, heapDate-gty ) free( heapDate )
d 4
heapDate
sizeof( struct Date )
m 10
y 3945
Remember x-gty means (x).y
The memory MUST be freed (eventually)
35Arrays of structs on the heap
36Arrays of structs on the heap
dobs0
d
arrayOfDates
m
y
dobs1
d
m
y
- What we would like
- An array of structs
- A pointer to the array, so that we can use it
dobs2
d
m
y
dobs3
d
m
y
dobs4
d
m
y
dobs5
d
m
y
dobs6
d
m
y
37Arrays of structs on the heap
dobs0
d
ArrayOfDates
m
y
dobs1
d
struct Date ArrayOfDates malloc( sizeof(struct
Date) 10 )
m
y
dobs2
d
m
- Allocate enough memory for 10 struct Dates
- Put the address into the struct Date pointer
- (Compiler assumes it points to a struct Date
Remember The type of the pointer matters) - 3) Pointers can be treated as arrays!
- (You know that there is enough memory to hold
all 10 elements of the array, so it is safe to do
this)
y
dobs3
d
m
y
dobs4
d
m
y
dobs5
d
m
y
dobs6
d
m
y
38Array of structs on the heap
malloc_struct.c
struct Date ArrayOfDates malloc(
sizeof(struct Date) 10 ) for ( i0 i lt
10 i ) printf( "ArrayOfDatesd is
02d/02d/04d before initialisation\n", i,
ArrayOfDatesi.d, ArrayOfDatesi.m,
ArrayOfDatesi.y )
Number of array elements
- ArrayOfDates0 is 04/10/3945 before
initialisation - ArrayOfDates1 is 00/00/0000 before
initialisation - ArrayOfDates2 is 00/00/0000 before
initialisation - ArrayOfDates3 is -111/-2/0000 before
initialisation - ArrayOfDates4 is 00/00/0000 before
initialisation - ArrayOfDates5 is 00/00/0000 before
initialisation - etc
39Initialising (zeroing) data
40memset( dest_addr, value, size )
memset(ArrayOfDates, 1, sizeof(struct Date)
10) for ( i0 i lt 10 i ) printf(
"ArrayOfDatesd is 02d/02d/04d after
initialisation\n", i, ArrayOfDatesi.d,
ArrayOfDatesi.m, ArrayOfDatesi.y
) free( ArrayOfDates )
Value to set all bytes to 1. This could be
anything, e.g. 0.
The memory MUST be freed (eventually)
- ArrayOfDates0 is 01/01/0257 after
initialisation - ArrayOfDates1 is 01/01/0257 after
initialisation - ArrayOfDates2 is 01/01/0257 after
initialisation - ArrayOfDates3 is 01/01/0257 after
initialisation - ArrayOfDates4 is 01/01/0257 after
initialisation - ArrayOfDates5 is 01/01/0257 after
initialisation - etc
41Declaring new names for types
42typedef
- Declare a new type name using typedef
- Usage
- typedef old_type new_name
- E.g.
- typedef struct DATE
- int d, m, y Date
- Code can then use type Date instead of struct
DATE - In C (not C) you can omit the keywords struct,
enum, union anyway - Similar to an automatic typedef
43Next lecture
- Input/output functions
- To/from screen/keyboard
- Actually stdin/stdout
- To/from files
- Including stdin and stdout
- Dynamically resizing arrays