COMP2006 Lecture 5 Structs
COMP2006 Lecture 5 Structs
C++ Programming
Lecture 5
Dr Chao Chen
1
This lecture
• C-type structs
– C++ builds on these and adds features
– Accessing operators (. and ->)
2
structs
3
structs
• We will start with C-type structs
– C++ structs and classes can be considered to be extensions of C
structs, e.g. allowing member functions, inheritance etc
– structs and classes are virtually the same thing in C++
• The only difference is default public or default private
• Examples:
– Group three integers together to specify a time:
struct Time
{
int hour;
int minute;
int second; Note the ; at the end!
};
– Shorter version, for day, month, year:
struct Date { int d, m, y };
4
Accessing members of a struct
Creates a
• Example: struct on
struct Date { int d, m, y; }; the stack
5
Accessing members of a struct
• Use the . operator to access members
– Exactly as for Java classes
• Example:
struct Date { int d, m, y; };
7
Array of structs (on the stack)
Date arrayOfDatesOnStack[5];
Array of 5 elements
for ( i=0 ; i < 5 ; i++ )
printf( "arrayOfDatesOnStack[%d] is : %02d/%02d/%04d\n",
i,
arrayOfDatesOnStack[i].d,
arrayOfDatesOnStack[i].m,
arrayOfDatesOnStack[i].y );
arrayOfDatesOnStack[0] is : 00/00/0000
arrayOfDatesOnStack[1] is : 02/00/0000
arrayOfDatesOnStack[2] is : -104/-51/0034
arrayOfDatesOnStack[3] is : -41/53/24833
arrayOfDatesOnStack[4] is : -71/-74/24854
initalisedArrayOfDatesOnStack[0] is : 01/01/2001
initalisedArrayOfDatesOnStack[1] is : 02/02/2002
initialisedArrayOfDatesOnStack[2] is : 03/03/2003
initialisedArrayOfDatesOnStack[3] is : 04/04/2004
9
initialisedArrayOfDatesOnStack[4] is : 05/05/2005
Passing structs into functions
struct Date dob = {1, 4, 1990};
12
The heap and malloc()
I need this many
• Avoid waste of memory bytes of memory:
malloc( size )
I no longer need
• free() when no longer this memory
free( address )
needed
HEAP
13
5 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. :
int* pInt = (int*)malloc( sizeof(int) );
Note: C++ needs the cast, C does not
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 );
14
malloc, calloc and realloc
• All of these functions return NULL on failure
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
15
Creating a simple array
int* pInt = (int*)malloc( sizeof(int) );
*pInt = 5;
(*pInt)++; Stack: Heap:
parray int
int iSize = 6;
int
int* parray = (int*)malloc(
iSize * sizeof(int) ); int
*parray = 3; /* Index 0 */ int
parray[5] = 5; int
free( parray ); int
16
Positioning of struct elements
17
Positions in memory
Like arrays, the positions of the members inside a
Time first struct are known
time Elements will be placed sequentially in memory, in
the order they are defined in the structure
day
Address Size
month dt 0x7fffaab18180 8
year dt.time 0x7fffaab18180 4
dt.day 0x7fffaab18184 1
dt.month 0x7fffaab18185 1
dt.year 0x7fffaab18186 2
18
Gaps when day is first
Day first
day 0x7fff69becaf0
time 0x7fff69becaf4
Size of structure: 12
month 0x7fff69becaf8
year 0x7fff69becafa
19
May have gaps at the end…
Month last
day 0x7fff69becaf0
time 0x7fff69becaf4
Size of structure: 12
year 0x7fff69becaf8
month 0x7fff69becafa
20
#pragma
21
Tell it to pack on 1 byte boundaries
#pragma pack(1)
day
time
Address Size
month
dt 0x7fff7e004280 8 year
dt.day 0x7fff7e004280 4
dt.time 0x7fff7e004281 1
dt.month 0x7fff7e004285 1
dt.year 0x7fff7e004286 2
22
Positions in memory
Time first Day first #pragma pack(1)
time day day
time
day time
month month
year year
month
year
23
Structs and component positions
struct DateTime printf(
{ "Address of dt = %p, size %d\n",
int time; &dt, sizeof(dt) );
char day;
char month; printf(
short year; "Address of dt.time = %p, size %d\n",
}; &(dt.time), sizeof(dt.time) );
printf(
"Address of dt.day = %p, size %d\n",
int main( int argc, &(dt.day), sizeof(dt.day) );
char* argv[] )
{ printf(
DateTime dt = { "Address of dt.month = %p,size %d\n",
80000, &(dt.month), sizeof(dt.month));
01,
04, printf(
1990 }; "Address of dt.year = %p, size %d\n",
&(dt.year), sizeof(dt.year) );
24
unions
Treating something as
“one thing OR another”
26
Unions
• Elements of unions are in the SAME place
• Elements of unions may be different sizes
– A union is as big as the biggest thing in it (plus
any packing)
• Unions are a way of providing different ways of looking
at the same memory Addr: ul ar
1000 [0]
union charorlong
1001 ul [1]
{
Size 4? 1002 [2]
unsigned long ul; 1003 [3]
char ar[8]; Size 8 1004 [4]
}; 1005 [5]
1006 [6]
27
1007 [7]
Predict the sizes
28
Sizes of unions and structs
• Be aware of packing issues
If there is no excess space for packing:
• sizeof(struct) is total of the size of the
members (i.e. sum of member sizes)
– Members are one after another in memory
• sizeof(union) is size of the largest
member (i.e. maximum of member sizes)
– All members are in the same place
– Largest member determines size
29
#pragma pack(1)
#include <cstdio>
NOT C!
32
C++ classes and structs
• Can still use structs in C++
• Everything for structs so far applies to both C and C++
– We will call them C-style structs or POD structs (Plain Old Data)
• If you use only C features:
– structs in C++ work as for C, i.e. you can predict sizeof(),
can malloc() space for them, etc
– Everything we have seen so far is valid for C++ POD structs
• C++ structs can also act as full classes though
– The only difference between a struct and class in C++ is default
access
– Structs default to public access, so you don’t need to say ‘public’
– Classes default to private access – methods and data is hidden
unless you say otherwise
– For the moment we will continue to use structs, to avoid issues 33
of
access privileges
C++ classes and structs
• For the moment we will use your Java knowledge and I
will tell you:
– You can add member functions to structs/classes
– You can add constructors – called when objects are created
– You can use new to create objects of a class
– You can pass parameters to a constructor
– You can have multiple different constructors
– You can also use inheritance with structs, defaults to public
• Unlike Java:
– You can also add destructors to objects
• Called automatically when object is destroyed
• Equivalent of calling constructor automatically when object is created
– You need to manually destroy heap objects
– Objects on the stack will be destroyed properly when the function
ends – including calling destructor.
– Will see later, you can write code to destroy objects on the stack
automatically when the last (smart) pointer to them is destroyed34
Example : new and delete
struct MyStruct
{
Create a new object
public:
of type MyStruct
int ai[4];
on the heap
short j;
};
Really creates the
int main()
object, e.g. calls the
{ constructor
MyStruct* pOb = new MyStruct;
MyStruct * pObArray = new MyStruct[4];
pOb->ai[2] = 3;
pObArray[3].j = 5; Uses default constructor
pObArray[1].ai[3] = 5; for each object in array
delete pOb;
delete [] pObArray; delete [] to match new []
return 0; 35
}
new vs malloc
MyClass* pOb = new MyClass;
• new knows how big the object is
– No call to sizeof() is needed (unlike malloc())
• new creates an object (and returns a pointer)
– Allocates memory (probably in same way as malloc())
• new knows how to create the object in memory
– C++ objects can consist of more than the visible data members
(an example later, with hidden vtable ptrs)
• new calls the constructor (malloc() will not!)
• new throws an exception (bad_alloc) if it fails
– By default, unless you tell it not to (e.g. new(nothrow) int)
– Some older compilers may return NULL – but new ones should
not (malloc() returns NULL on failure)
– Ignore this for the moment! 36
delete, new[] and delete[]
• delete destroys an object
– More about this later
MyClass* pOb = new MyClass;
delete pOb;
• new and delete have a [] version for
creating and destroying arrays
– Default constructor is called for the elements
• You MUST match together:
new and delete
new [] and delete []
malloc() and free() 37
Next lecture