pointers 2 cop3275 – programming using c diego j. rivera-gutierrez
TRANSCRIPT
Pointers 2COP3275 – PROGRAMMING USING C
DIEGO J. RIVERA-GUTIERREZ
Administrative stuff
• Quiz on Friday• Easy question on pointers (regarding basic operators + malloc) (15
pts)• Create one function that does an operation to the list we will create
today (15 pts)• String function (15 pts)• Free credit question. (Every answer is correct for this one – 5pts)
• Homework #5 will be posted tonight.
Homework #5
• Allow different sizes of boards!
• Move seed, # of mines and board size to console arguments.• -s for seed• -m for mines• -r for rows• -c for columns
• Include mine counter (#mines – mines assigned)
• Winning condition – including when all unopened tiles are mines
• Due on July 24th.
Let’s build a better list…
• We have a struct that saves all the info for a student (name, UFID, DOB, major, year, etc).
struct student{char *name;int UFID;char major[3];struct Date DOB;int year;
};
Let’s build a better list…
• For simplicity let’s only use name
struct student{char *name;struct student *next;
};
Remember what we are after:
Ana Andrew Cristina Juliana Michael
On Monday – Creation of the list
struct student ana;ana.name = "Ana";
struct student andrew;andrew.name = "Andrew";
ana.next = &andrew;
• That works fine. But it’s not ideal. • Very manual..
• We want functions to handle operations so we likely want an “add” function.
What functions we need?
• Add• Add keeping alphabetical order!
• Delete
• Search?
The add function
• What are our parameters?• Current list• Element to add
• What’s the current list at the very beginning?
• What would you consider to be an “empty” list?• NULL!
• Do we need a return value?• Yes! Why? To be able to delete the front!
Add function
• Return type: struct student *
• Name: Add
• Parameter 1: struct student * current_list
• Parameter 2: ?• char * name?• struct student s1?• struct strudent *s2?
Add functionstruct student *add(struct student *list,
char* name) {
struct student s;s.name = name;s.next = NULL;
if(list == NULL) {
return &s;
}else {
struct student *pos = list;
while((*pos).next != NULL) {pos = (*pos).next;}
(*pos).next = &s;return list;}
}
Note: This has a major error!
Before we get to the error – The ‘->’ operator
• The notation (*pos).next is kind of annoying.
• Having to “de-reference” the pointer to access the struct’s elements is a very common task
• We have a special operator that does this! The ‘->’ operator
• So if ptr is a pointer to a struct that has id as one of the its elements:
ptr->id is equivalent to (*ptr).id
pos->next is equivalent to (*pos).next
The -> operator struct student *add(struct student *list,
char* name) {
struct student s;s.name = name;s.next = NULL;
if(list == NULL) {
return &s;
}else {
struct student *pos = list;
while(pos->next != NULL) {pos = pos->next;}
pos->next = &s;return list;}
}
Note: This has a major error!
If we compile that, we get a warning about the error!
list.c:17:3: warning: function returns address of local variable [-Wreturn-local-addr]
return &s;
^
• The warning is pretty clear.
• We are returning the memory address of a “local variable”
• If you remember from our discussion on scopes:
• A “local variable” is a variable defined inside a function• As opposed o a “global variable” that is accessible in the full scope
of the program
So what’s the error?struct student *add(struct student *list,
char* name) {
struct student s;s.name = name;s.next = NULL;
if(list == NULL) {
return &s;
}else {
struct student *pos = list;
while(pos->next != NULL) {pos = pos->next;}
pos->next = &s;return list;}
}
Ok… so maybe we could receive the struct?struct student *add(struct student *list,
struct student s) {
if(list == NULL) {
return &s;
}else {
struct student *pos = list;
while(pos->next != NULL) {pos = pos->next;
}
pos->next = &s;return list;
}}
This is still an issue… Structs are passed by valueAnd parameters are also local variables…
Can we finally see one version that runs?struct student *add(struct student *list,
struct student *s) {
if(list == NULL) {
return s;
}else {
struct student *pos = list;
while(pos->next != NULL) {pos = pos->next;
}
pos->next = s;return list;
}}
Ok are we happy with add now?
• Nope. But, why?
• Right now to add a new student we need to do something like this:
struct student s = { .name = “Name”, .next = NULL};list = add(list, &s);
• What happens if the user can input the students?
• How many struct student do we need to allocate?
• We could potentially allocate an array so that we have structs to take from.
• The problem with that is: how many are enough? What happens if the user wants just one more than we gave them?
• It becomes very inneficcient.
• The solution: malloc!
malloc (also in the Advanced Features Chapter)
• REALLY? Advanced features??? And pointer arithmetic is part of the pointer chapter??• Sorry I needed to complain about that decision the book author made.
• malloc is defined in stdlib.h • It stands for memory allocation.
• Malloc “dynamically” allocates memory
• It receives a single parameter of type size_t with the number of bytes to allocate• size_t is a custom type and it’s actual meaning is platform (computer)
dependent• Usually it is an unsigned long int (but not necessarily) • We’ve seen size_t before when we talked about the sizeof function.
• It returns a void* (a pointer to type void).• This is C’s “generic” pointer.• It can point to anything! Including code (recall my awkward discussion
about calling functions without a name)
malloc
• So how do I use it?
int *ptr_int = (int*)malloc(4);
• Wait don’t use it like that….
• Even if we know that an int is 4 bytes for most of our uses….
• This ties our code to architectures that use 4 byte integers.
• The correct way of using it:
int *ptr_int = (int*)malloc(sizeof(int));
malloc – Graphically explained
int *ptr_int;
ptr_int = (int*)malloc(sizeof(int));
?
malloc – Graphically explained
int *ptr_int;
ptr_int = (int*)malloc(sizeof(int));
?
<int>
At this point this piece of memory isnot named. It is valid memory, but it’s not tiedto a variable name.
malloc – Graphically explained
int *ptr_int;
ptr_int = (int*)malloc(sizeof(int));
?
<int>
So how do we use it for our add function?struct student *add(struct student *list,
char* name) {
struct student s;s.name = name;s.next = NULL;
if(list == NULL) {
return &s;
}else {
struct student *pos = list;
while((*pos).next != NULL) {pos = (*pos).next;
}
(*pos).next = &s;return list;
}}
So how do we use it for our add function?struct student *add(struct student *list,
char* name) {
struct student *s = (struct student*)malloc(sizeof(struct student));
s->name = name;s->next = NULL;
if(list == NULL) {
return s;
}else {
struct student *pos = list;
while((*pos).next != NULL) {pos = (*pos).next;
}
(*pos).next = s;return list;
}}
Delete function
• We will delete by index (same as we did before).
void delete(struct student *list,
int index) {
struct student *prev;struct student *current = list;
while(index > 0 ) {
index--;prev = current;current = current->next;
}
prev->next = current->next; }
Allowing deleting the head(We all want to get rid of Ana)
• Ok she is my best friend, so no we don’t…. But if we did... The current way doesn’t support that.
• We can do it recursively (and we also don’t need to take into account the previous! Which is cool!)
struct student *delete2(struct student *list,
int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next,
index-1);return list;
}}
Freeing memory
• We are dynamically asking for memory.
• Remember memory is a limited resource. • It is BIG for most of our applications. But it’s not infinite.
• Every time we call malloc, we are making a commitment to use that memory and eventually free it.
• Not freeing memory is bad…• It’s like punching your mom… like that bad…
• Ok maybe not THAT bad….
• When the program ends, all memory gets reclaimed• OS programmers are smart dudes…
• But we should always try to use memory responsibly
Freeing memory
• free is the function we use to free up memory we have created using malloc.
• free receives any pointer, it goes to that piece of memory and let’s the OS reclaim the memory.
• free(ptr_int);
Delete function
struct student *delete(struct student *list,
int index) {
struct student *prev;struct student *current = list;
while(index > 0 ) {
index--;prev = current;current = current->next;
}
prev->next = current->next;
free(current);
return list;}
Recursive delete
struct student *delete(struct student *list,
int index) {
if(index == 0) {
struct student *next = list->next;free(list);return next;
}else {list->next = delete(list->next, index-
1);return list;
}}
Why like that?
PointersFRIDAY JULY, 10TH
Administrative Stuff
• Quiz today.
• Quiz #5 grades were released yesterday.
• Homework #5 was posted.
• The solution to Homework #4 was also posted.
• Let’s check the homework specification.
Recursive delete
struct student *delete2(struct student *list,
int index) {
if(index == 0) {
struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next,
index-1);return list;
}}
Recursive delete
struct student *delete2(struct student *list,
int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next,
index-1);return list;
}}
Ana Andrew Cristina Juliana Michael
struct student *delete2(struct student *list,int index) {if(index == 0) {
return list->next;}else {
list->next = delete2(list->next, index-1);return list;
}}
list = delete2(list, 2);
list
list
delete2(list, 2)
list
delete2( , 2)AnaAndre
wCristin
a Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
list
delete2( , 2)AnaAndre
wCristin
a Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
list
delete2( , 2)AnaAndre
wCristin
a Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
list
delete2( , 2)AnaAndre
wCristin
a Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
list
delete2( , 2)AnaAndre
wCristin
a Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 2-1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 1-1)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
CristinaJuliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
CristinaJuliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
CristinaJuliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
Juliana
list
delete2( , 2)Ana
Andrew
CristinaJuliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
delete2( , 2)Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
Ana
Andrew
Cristina
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {return list->next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
Juliana
list
Ana
Andrew
Cristina
Juliana Michael
list = delete2(list, 2);
Juliana
list
Ana
Andrew
Cristina
Juliana Michael
Juliana
list
Ana
Andrew
Cristina
Juliana Michael
void print(struct student *head) { while(head != NULL) {
printf("%s\n", (*head).name); head = (*head).next;
} }
list
Ana
Andrew
Cristina
Juliana Michael
void print(struct student *head) { while(head != NULL) {
printf("%s\n", head->name); head = head->next;
} }
list
Ana
Andrew
Cristina
Juliana Michael
void print(struct student *head) { while(head != NULL) {
printf("%s\n", head->name); head = head->next;
}} print(list);
list
Ana
Andrew
Cristina
Juliana Michael
void print(struct student *head) { while(head != NULL) {
printf("%s\n", head->name); head = head->next;
}} print(list);
Cristina is no longer accessible from theHead (list). However, she is still in memory.
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
next
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
next
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
next
list
delete2( , 2)Ana
Andrew
Cristina Juliana Micha
el
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
next
list
delete2( , 2)Ana
Andrew
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
delete2( , 0)
next
list
delete2( , 2)Ana
Andrew
Juliana Michael
struct student *delete2(struct student *list,int index) {
if(index == 0) {struct student *next = list->next;free(list);return next;
}else {list->next = delete2(list->next, index-
1);return list;
}}
delete2( , 1)
next
Questions?
Using malloc to create variable size arrays….