C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for.

Similar presentations

Presentation on theme: "C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for."— Presentation transcript:

1
C Structures and Memory Allocation There is no class in C, but we may still want non- homogenous structures –So, we use the struct construct struct for structure –A struct is a data structure that comprises multiple types, each known as a member each member has its own unique name and a defined type –Example: A student may have members: name (char[ ]), age (int), GPA (float or double), sex (char), major (char[ ]), etc –If we want to create a structure that can vary in size, we will allocate the struct on demand and attach it to a previous struct through pointers Here, we examine structs, allocation techniques, and linked structures

2
The struct Definition struct is a keyword for defining a structured declaration Format: name represents this structure’s tag and is optional –we can either provide name –or after the } we can list variables that will be defined to be this structure We can also use typedef to declare name to be this structure and use name as if it were a built-in type –typedef will be covered later in these notes struct name { type1 name1; type2 name2; … }; name1 and name2 are members of name

3
Examples struct point { int x; int y; }; struct point p1, p2; p1 and p2 are both points, containing an x and a y value struct { int x; int y; } p1, p2; p1 and p2 both have the defined structure, containing an x and a y, but do not have a tag struct point { int x; int y; } p1, p2; same as the other two versions, but united into one set of code, p1 and p2 have the tag point For the first and last sets of code, point is a defined tag and can be used later (to define more points, or to declare a type of parameter, etc) but in the middle code, there is no tag, so there is no way to reference more examples of this structure

4
Accessing structs A struct is much like an array –The structure stores multiple data You can access the individual data, or you can reference the entire structure –To access a particular member, you use the. operator as in student.firstName or p1.x and p1.y –we will see later that we will also use - > to reference a field if the struct is pointed to by a pointer –To access the struct itself, reference it by the variable name Legal operations on the struct are assignment, taking its address with &, copying it, and passing it as a parameter –p1 = {5, 10};// same as p1.x = 5; p1.y = 10; –p1 = p2;// same as p1.x = p2.x; p1.y = p2.y;

5
structs as Parameters We may pass structs as parameters and functions can return structs –Passing as a parameter: void foo(struct point x, struct point y) {…} –notice that the parameter type is not just the tag, but preceded by the reserved word struct –Returning a struct: struct point createPoint(int a, int b) { struct point temp; temp.x = a; temp.y = b; return temp; }

6
Inputting a struct in a Function We will need to do multiple inputs for our struct –Rather than placing all of the inputs in main, let’s write a separate function to input all the values into our struct The code to the right does this –But how do we pass back the struct? Remember C uses pass by copy –the struct is copied into the function so that p in the function is different from y in main –after inputting the values into p, nothing is returned and so y remains {0, 0} #include struct point { int x; int y; }; void getStruct(struct point); void output(struct point); void main( ) { struct point y = {0, 0}; getStruct(y); output(y); } void getStruct(struct point p) { scanf("%d", &p.x); scanf("%d", &p.y); printf("%d, %d", p.x, p.y); } void output(struct point p) { printf("%d, %d", p.x, p.y); }

7
One Solution For Input In our previous solution, we passed the struct into the function and manipulated it in the function, but it wasn’t returned –Why not? Because what was passed into the function was a copy, not a pointer So structs differ from arrays as structs are not pointed to In our input function, we can instead create a temporary struct and return the struct rather than having a void function struct point inputPoint( ) { struct point temp; scanf(“%d”, &temp.x); scanf(“%d”, &temp.y); return temp; } void main( ) { struct point y = {0, 0}; y = getStruct( ); output(y); } We could also pass the address of y and treat the struct like an array, we will see this next, but it requires a change in how we handle the members of the struct

8
Pointers to Structs The previous solution had two flaws: –It required twice as much memory we needed 2 points, one in the input function, one in the function that called input –It required copying each member of temp back into the members of the original struct with our point type, that’s not a big deal because there were only two members, but this may be undesirable when we have a larger struct –So instead, we might choose to use a pointer to the struct, we pass the pointer, and then we don’t have to return anything – scanf will follow the pointer and place the datum in our original struct We see an example next, but first… If a is a pointer to a struct, then to access the struct’s members, we use the - > operator as in a->x

10
Nested structs In order to provide modularity, it is common to use already- defined structs as members of additional structs Recall our point struct, now we want to create a rectangle struct –the rectangle is defined by its upper left and lower right points Now consider the following struct rectangle r, *rp; rp = &r; Then the following are all equivalent r.pt1.x rp->pt1.x (r.pt1).x (rp->pt1).x But not rp->pt1->x (since pt1 is not a pointer to a point) struct point { int x; int y; } struct rectangle { struct point pt1; struct point pt2; } If we have struct rectangle r; Then we can reference r.pt1.x, r.pt1.y, r.pt2.x and r.pt2.y

11
Arrays of structs To declare an array of structs (once you have defined the struct): –struct rectangle rects[10]; –rects now is a group of 10 structures (that consist each of two points) –You can initialize the array as normal where each struct is initialized as a { } list as in {5, 3} for a point or {{5, 3}, {8, 2}} for a rectangle The array of structs will be like the array of classes that we covered in 260/360, we will use this data structure if we want to create a database of some kind and apply such operations as sorting and searching to the structure

13
typedef typedef is used to define new types –The format is typedef description name; –Where description is a current type or a structural description such as an array declaration or struct declaration –Examples: typedef int Length;// Length is now equivalent to the type int typedef *char[10] Strings; // Strings is the name of a type for an array of 10 strings typedef struct node {// declares a node structure that contains int data;// a data item and a pointer to a struct of type node struct node *next; }; We can simplify our later uses of node by doing the following typedef struct node aNode;// this allows us to refer to aNode instead of struct node

14
Memory Allocation To this point, we have been declaring pointers and having them point at already created variables/structures –However, the primary use of pointers is to create dynamic structures structures that can have data added to them or deleted from them such that the amount of memory being used is equal to the number of elements in the structure this is unlike an array which is static in size –An ordinary variable has its memory created at compile time so is fixed in size –The pointer can point to a piece of memory that has just been created (allocated) –We will use this approach (memory allocation + pointers) to create data structures like linked lists and trees Note: in Java, allocation was done whenever you used the new reserved word as in ClassName x = new ClassName(…);

15
malloc and calloc The two primary memory allocation operations in c are malloc and calloc –The main difference between them is that calloc provide a chunk of contiguous memory – we will use this for the creation of an array –For most situations, we will use malloc, which has the form: pointer = (type *) malloc(sizeof(type)); This sets pointer to point at a newly allocated chunk of memory that is the type specified and the size needed for that type –NOTE: pointer will be NULL if there is no more memory to allocate –The cast may not be needed, but is good practice –calloc has the form: pointer = (type *) calloc(n, sizeof(type)); // n is the size of the array –Another C instruction is free, to free up the allocated memory when you no longer need it as in free(pointer);

16
calloc example The most common use of calloc is for flexible sized arrays (to change the size) using an approach like the “array doubling” used in Java – but here, we use calloc to allocate the array #include #include // needed for calloc void main() { int i; int *x, *y;// two pointers to int arrays x = (int *) calloc(10, sizeof(int));// x now points to an array of 10 ints for(i=0;i<10;i++) x[i] = i;// fill the array with values …// oops, need more room than 10 y = (int *) calloc(20, sizeof(int));// create an array of 20, temporarily // pointed to by y for(i=0;i<10;i++) y[i] = x[i];// copy old elements of x into y free(x);// release memory of old array for(i=10;i<20;i++) y[i] = i;// add the new elements x = y;// reset x to point at new, bigger array } An example of malloc is given on my web site rather than here as it is too large to fit

17
Linked Structures Our last topic is in building linked structures –lists, trees These are dynamic structures, when you want to add a node, you allocate a new chunk of memory and attach it to the proper place in the structure via the pointers –Each node in the structure will have at least one datum and at least one pointer –In linked lists, the pointer is a next pointer to the next node in the list, in a tree, there are left and right children pointers –We will use malloc to allocated the node –We will need to traverse the structure to reach the proper place to insert a new node A linked list example is given separately on my web site

18
Declarations for Nodes struct node { int data; struct node *next; }; node *front; front is a pointer to the first node in a linked list. It may initially be NULL. Traversing our linked list might use code like this: temp = front; while(temp!=NULL) { // process temp temp=temp->next; } struct treeNode { int data; struct treeNode *left; struct treeNode *right; }; Our root node will be declared as treeNode *root; It is common in trees to have the root node point to the tree via the right pointer only with the left pointer remaining NULL