Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile.

Similar presentations


Presentation on theme: "Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile."— Presentation transcript:

1 Chapter 0.2 – Pointers and Memory

2 Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile  lookup the value of the variable on every single access, do not cache, store in a register, or use in optimisation  used for memory mapping  implementation dependent; no required semantics  sometimes broken  restrict  Applied to a pointer  indicates that the pointer is the only way to access the contents of the address  improves optimization by preventing pointer aliasing  atomic  It's new and I don't really know what it does... Research suggests it can be used to somewhat cause a type or function to be atomic with respect to pre-emption

3 Strings  In C, a string is nothing more than an array of characters.  There is no field to store the length or any other data about the string.  To mark the end of the string, a NULL value (i.e., all bits zero) is used.  String library functions expect there to be a terminating NULL character.  Because a string is an array, I'm going to ignore them when talking about memory and only discuss arrays.

4 Memory Management  C is nothing but glorified assembly language  To program in C effectively, one needs an understanding of: a. the memory model b. calling conventions  Three basic ideas: 1. Static memory – things that don't change 2. Stack memory – things associated with function calls 3. Heap memory – globals, runtime allocation, etc.

5 Basic Memory Model

6 The Stack Every function call creates a stack frame that contains: 1. Arguments (values for parameters) 2. Return address 3. Context (saved register values) 4. Local variables Val/Address Arg 2: EBP + 12 Val/Address Arg 1: EBP + 8 Return Address Old/Saved EBP Local Variable 1: EBP - 4 Local Variable 2: EBP - 8 EAX (saved) … EDX (saved) Empty Space

7 Stack Storage  The stack stores words (i.e., 64 bit values that can fit in a register )  Anything that can't fit on the stack is generally stored in the heap and it's address put on the stack  Thus, we have to know where something is located to know if we have a value or an address

8 Storage Classes  We can somewhat control where things are stored using storage classes  auto : give the variable automatic storage on the stack; can only be used in functions  register : try to keep the variable in a register; may by ignored; & cannot be used on register variables  static  inside functions, the variable retains it value between function calls (heap variable, not stack)  outside functions, it indicates a variable declaration cannot be linked to other compilation units (files)  extern : declare the variable; storage will be defined elsewhere and location determined at link time

9 Calling Conventions  We put arguments (values for function parameters) on the stack when we call a function.  Call by Value: We are putting a value (e.g., int, float, char) on the stack.  Call by Reference: We are putting the address of the value(s) on the stack. The value is somewhere else (possibly the heap).

10 Arrays  Arrays are kept in heap storage.  The stack only ever stores the address.  A pointer is a variable that stores an address.  To manipulate arrays, we can offset from the base address using [] notation to obtain a value.  We can also use the pointer directly and we can make pointers for non-arrays if desired.

11 Syntax  Variables can be declared as pointer by prefixing them with *. int *x;  Pointers can be dereferenced – that is, the value from the stored address is obtained. int z = *x;  The address of something can be obtained by prefixing it with &. x = &argc;  NOTE: It is bad if you take the address of something on the stack that can go away!

12 Pointers int x = 5; int *p; p = &x; printf ("%d %d", x, *p);  * := LHS, "is a pointer"  := RHS, "take value of"  & := "take address of"

13 Example int x = 1, y = 2, z[10]; int *ip; /* ip is pointer to integer */ ip = &x; /* ip points to x */ y = *ip; /* y is now 1, the value in x */ *ip = 0; /* x is now 0 */ ip = &z[0]; /* ip points to z[0] */ *ip = y; /* z[0] now 1, the value in y */

14 Why we need pointers... void swap (int x, int y) { int tmp = x; x = y; y = tmp; }  x and y are on the stack and use call by value  This function swaps the values of two stack variables that go away when the function returns causing x, y to be deleted.

15 Using Pointers void swap (int *px, int *py) { int tmp = *px; *px = *py; *py = tmp; } int x = 1, y = 2; swap (&x, &y);

16 Function Pointers  There are no objects and methods  However, we can pass a function around without using an object  We simply pass the address of the function (since it's in memory as well)  Function names, like array names, are actually addresses  When using a function pointer we need to dereference the address to action the code

17 Example: Function Pointer #include void fun (int a) { printf("Value of a is %d\n", a); } int main () { /* Define and initialise a function pointer */ void (*fun_ptr)(int) = &fun; /* Invoke fun() using fun_ptr */ (*fun_ptr)(10); return 0; }

18 Function Pointers void bsearch ( const void *key, const void *base, size_t n, size_t size, int (*cmp)(const void *keyval, const void *datum) ); char data[256][64]; bsearch("tami",data,64*sizeof(char),256,strcmp); Notes: void* is typically used to mean "pointer to anything" size_t is the type of the integers that are returned by sizeof

19 Dynamic Memory Management  We can put things on the heap at runtime  For example we can request heap space into which we can read a file's contents  We use malloc() to do memory allocation  When the memory is no longer needed, we can use free() to release it for re-use  Java provides a "garbage" collector to manage the heap for us... in C we do it ourselves.

20 Example: Dynamic Memory /* Allocate a pair of buffers */ char *buf1 = malloc(256 * sizeof (char)); char *buf2 = calloc(256, sizeof(char)); /* resize buf1 and “leak” buf2 */ buf2 = realloc(buf1, 128 * sizeof (char)); /* Cause a runtime error with a double free */ free(buf1), free(buf2);

21 Definitions and Declarations  Declarations say something exists. They provide enough information so that the file can be compiled.  Where the declared entity will be located is determined during linking.  The mechanism is in place to support the individual compilation of files and is the basis of "header files" (which mostly store declarations)  Definitions assign memory to something.

22 Complex Declarations  char **argv  pointer to pointer to char  int (*daytab)[13]  pointer to array[13] of int  int *daytab[13]  array[13] of pointer to int  void *comp()  function return pointer to void  void (*comp)()  pointer to function returning void

23 Insane Declarations  char (*(*x())[])()  function returning pointer to array[] of pointers to functions returning char  char(*(*x[3])())[5]  array[3] of pointers to functions returning pointer to array[5] of chars

24 Structures: Records for Data /* Method A: Not using typedef */ struct point { int x; int y; }; struct point origin = { 0, 0 }; /* Method B: Compressed version of method A */ struct point { int x; int y; } origin = { 0, 0 }; /* Method C: Using typedef */ typedef struct { int x; int y; } point_t; point_t origin = { 0, 0 };

25 Recursive Structures typedef struct node { char *data; struct node next; } node_t; node_t *list = malloc(sizeof(node_t)); list->data = “Meredith”; list->next = NULL; node_t *list2 = malloc(sizeof(node_t)); list2->data = “Tami”; list2->next = list;

26 Unions  Unions are used to save memory  The size of a union is equal to the size of the largest field  It is up to the programmer to use the fields correctly union number { int ival; float fval; } n; n.ival = 1; printf(“%f\n”, n.fval); /* works, but not a cast */

27 Do you ?


Download ppt "Chapter 0.2 – Pointers and Memory. Type Specifiers  const  may be initialised but not used in any subsequent assignment  common and useful  volatile."

Similar presentations


Ads by Google