pointers and structs returning multiple values
play

Pointers and Structs Returning Multiple Values 1 Returning two - PowerPoint PPT Presentation

Pointers and Structs Returning Multiple Values 1 Returning two Values from a Function We want to return o the sum of all the elements in an array (an int) and o whether 42 is in the array (a bool) C0 functions return C0 functions return at


  1. Pointers and Structs

  2. Returning Multiple Values 1

  3. Returning two Values from a Function  We want to return o the sum of all the elements in an array (an int) and o whether 42 is in the array (a bool) C0 functions return C0 functions return at most one value at most one value ??? sum_and_42(int[] A, int n) //@requires n == \length(A); { int sum = 0; int main() { bool has_42 = false; int[] A = alloc_array(int, 10); for (int i = 0; i < n; i++) { for (int i = 0; i < 10; i++) A[i] = i - 5; sum += A[i]; if (A[i] == 42) has_42 = true; ??? = sum_and_42(A, 10); } return 0; } }  How can we do that? 2

  4. Returning two Values from a Function  A C0 function can communicate with its caller o by returning a value to it or o by modifying a value in allocated memory the caller shared with it  Idea: o main passes a 1-element int array S to sum_and_42 o sum_and_42 stores the sum in S Local Memory Allocated Memory o it returns whether 42 main is in the array as a bool … 0 n A S 0 sum_and_42 A sum goes sum here 3

  5. Returning two Values from a Function  A C0 function can communicate with its caller o by returning a value to it or o by modifying a value in allocated memory the caller shared with it  Idea: caller pass a 1-element int array to store the sum and function return a bool bool sum_and_42(int[] A, int n, int[] sum) //@requires n == \length(A); //@requires \length(sum) == 1; { sum[0] = 0; int main() { bool has_42 = false; int[] A = alloc_array(int, 10); for (int i = 0; i < n; i++) { for (int i = 0; i < 10; i++) A[i] = i - 5; sum[0] += A[i]; if (A[i] == 42) has_42 = true; int[] S = alloc_array(int, 1); } bool b = sum_and_42(A, 10, S); return has_42; return 0; } } 4

  6. Returning two Values from a Function  Idea o caller pass a 1-element int array to store the sum and o function return a bool  This is clunky: invoke the whole array machinery for a single cell in allocated memory! bool sum_and_42(int[] A, int n, int[] sum) //@requires n == \length(A); //@requires \length(sum) == 1; Yuck! { sum[0] = 0; int main() { bool has_42 = false; int[] A = alloc_array(int, 10); for (int i = 0; i < n; i++) { for (int i = 0; i < 10; i++) A[i] = i - 5; sum[0] += A[i]; if (A[i] == 42) has_42 = true; int[] S = alloc_array(int, 1); } bool b = sum_and_42(A, 10, S); return has_42; return 0; } } 5

  7. Pointers 6

  8. Memory Cells and Pointers  C0 provides o a way to create individual cells in allocated memory Creates a new cell in allocated memory alloc(int) Returns the memory address of the new cell Type of the values we can put in this cell o and pointers to manipulate them The memory address of the new cell is stored in p int* p = alloc(int) The type of pointers to a cell that can contain an int 7

  9. Memory Cells and Pointers int* p = alloc(int) Local Memory Allocated Memory o creates a new cell 0x8c4 o the returned address p 0x8C4 is stored in p This cell can p can only* contain only contain an int addresses An int pointer to cells of type int A cell of type int * Well, almost. We’ll revisit this.  Similar to arrays o Specific addresses are not visible within the program  We write arrows o Memory cells are Local Memory Allocated Memory initialized to default value for their type p 0 Default value of type int 8

  10. Working with Pointers  We read and write to a memory cell through a pointer to it *p … Follow the pointer in p and return the or write a new value in the cell value in the cell o This is called dereferencing p Prints 0 printint(*p); *p = 42; Puts 42 in the cell pointed by p printint(*p); Prints 42 Local Memory Allocated Memory p 42 9

  11. Aliasing  Pointers are subject to aliasing … q and p point to Local Memory Allocated Memory the same cell int* q = p; p 42 printint(*q); Prints 42 q Local Memory Allocated Memory *q = 7; p 7 printint(*p); Prints 7 q 10

  12. Garbage Collection  … and memory cells are subject to garbage collection o when there is no way to access them Local Memory Allocated Memory p = alloc(int); 7 *p = 3; p q = alloc(int); 3 q 0 11

  13. Functions on Pointers  A function that halves the content of an int cell o half is passed void half(int* x) { Local Mem. Alloc. Mem. Here *x = *x / 2; the value of p main }  an address 9 p int main() { Here half int* p = alloc (int); x *p = 9; half(p); There assert(*p == 4); o It modifies the same cell p points to return 0;  upon returning, } Local Mem. Alloc. Mem. the cell pointed by p contains 4 main 4 p There  Aliasing at work! half x Decommissioned 12

  14. Returning two Values from a Function Local Mem. Alloc. Mem.  This is how we solve our main … 0 n problem using pointers A o caller pass an int* to store the sum and S 0 o function return a bool Default int sum_and_42 A bool sum_and_42(int[] A, int n, int* sum) sum //@requires n == \length(A); { *sum = 0; int main() { bool has_42 = false; int[] A = alloc_array(int, 10); for (int i = 0; i < 10; i++) A[i] = i - 5; for (int i = 0; i < n; i++) { *sum += A[i]; if (A[i] == 42) has_42 = true; int* S = alloc(int); } bool b = sum_and_42(A, 10, S); return has_42; return 0; } } 13

  15. Returning two Values from a Function Local Mem. Alloc. Mem.  We can even share both main … 0 n via allocated memory A o caller pass an int* to store the sum S 0 o and a bool* to store whether 42 is b false in the array Default bool sum_and_42 A void sum_and_42(int[] A, int n, int* sum, bool* has_42) sum //@requires n == \length(A); { has_42 *sum = 0; int main() { *has_42 = false; int[] A = alloc_array(int, 10); for (int i = 0; i < n; i++) { for (int i = 0; i < 10; i++) A[i] = i - 5; *sum += A[i]; if (A[i] == 42) *has_42 = true; int* S = alloc(int); } bool* b = alloc(bool); } sum_and_42(A, 10, S, b); return 0; } 14

  16. Returning two Values from a Function  Real world example http://man7.org/linux/man-pages/man3/sincos.3.html 15

  17. Summary  Memory cells are kind of like 1-element arrays o Live in allocated memory o Subject to aliasing o Garbage collected  But they are not array! Linux Terminal Type error! Type error! --> int* p = alloc_array(int, 1); <stdio>:1.10-1.29:error:type mismatch expected: int* found: int[] --> int[] A = alloc(int); o int* and int[] are distinct type <stdio>:1.11-1.21:error:type mismatch expected: int[]  Not interchangeable! found: int* 16

  18. NULL 17

  19. Double Pointers  What does this do? Local Mem. Alloc. Mem. int** w = alloc(int*); w o Create a cell that can contain an int* Contains Type int** an int*  What is the default value of type int*? o Let’s ask coin Linux Terminal --> int** w = alloc(int*); w is 0x1D75260 (int**) --> *w; NULL (int*)  What is NULL? 18

  20. NULL  What is NULL? Local Mem. Alloc. Mem. o The default value of any pointer type w o Drawn as NULL Type int**  A value of pointer type can be either o an address to a cell in allocated memory, or o NULL  We can check if a pointer is NULL Linux Terminal --> w == NULL; true (bool) --> *w == NULL; true (bool) 19

  21. NULL  What is NULL good for? Local Mem. Alloc. Mem. Linux Terminal w --> int** w = alloc(int*); w is 0x1D75260 (int**) --> *w; We are accessing the value NULL (int*) contained in *w, i.e., we are dereferencing NULL --> **w; Error: null pointer was accessed o NULL is not the address of a memory cell  We can dereference addresses to memory cells  But, we are getting an error instead  Dereferencing NULL is a safety violation This is bad! 20

  22. The Billion Dollar Mistake  Tony Hoare introduced the NULL pointer in Algol W in 1965  Part of most imperative programming languages ever since o C, C++, Python, Javascript , PHP, …  One of the most error-prone programming constructs! This led me to suggest that the null value is a member of every type, and a null check is required on every use of that reference variable, Trillions by now and it may be perhaps a billion dollar mistake . -- Tony Hoare (InfoQ 2009 -- minute 27:40) o Every time we dereference a pointer, we need to know it is not NULL  Many programmers forget Linux Terminal  Endless source of bugs # ./a.out attempt to dereference null pointer Segmentation fault (core dumped) 21

  23. Pointer Safety Dereferencing NULL is a safety violation  *p has the precondition //@requires p != NULL; o Every time we dereference a pointer, we need to have a reason to believe it is not NULL  point-to reasoning!  alloc(tp) has the postcondition //@ensures \result != NULL; Linux Terminal --> int** w = alloc(int*); w is 0x1D75260 (int**) Is this safe? --> *w; YES: w != NULL by postcondition of alloc NULL (int*) 22

  24. Pointer Safety  Is our earlier code safe? o We are dereferencing sum, but we don’t know it’s not NULL o Add a precondition to ensure safety //@requires sum != NULL; A common contract when working with pointers bool sum_and_42(int[] A, int n, int* sum) //@requires n == \length(A); { *sum = 0; int main() { int[] A = alloc_array(int, 10); bool has_42 = false; for (int i = 0; i < 10; i++) A[i] = i - 5; for (int i = 0; i < n; i++) { *sum += A[i]; if (A[i] == 42) has_42 = true; int* S = alloc(int); } bool b = sum_and_42(A, 10, S); return 0; return has_42; } } 23

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend