CP264 Lecture 5 Pointers PDF
Document Details

Uploaded by HaleNeodymium
Wilfrid Laurier University
Tags
Summary
These lecture notes cover the concept of pointers in C programming, including pointer operations, special and generic pointers, and memory allocation in C. Understanding the different types of pointers and memory allocation is an essential step for all computer science undergraduates.
Full Transcript
Lecture 5 Pointers 1. Concepts of pointers 2. Pointer operations 3. Special pointers 4. Application of pointers 5. Memory allocations in C 1. Concept of Pointers A pointer is a variable that stores the memory address of another variable. The general syntax of declaring a pointer:...
Lecture 5 Pointers 1. Concepts of pointers 2. Pointer operations 3. Special pointers 4. Application of pointers 5. Memory allocations in C 1. Concept of Pointers A pointer is a variable that stores the memory address of another variable. The general syntax of declaring a pointer: data_type* ptr; // declare pointer ptr of data_type data_type x ; ptr = &x; // assign address of x to ptr The * informs the compiler that ptr is a pointer type variable and data_type specifies that it will store the address of a data_type type variable. We say ptr points to x, or points to memory location of x Dereferencing a pointer is to get the value stored the at memory pointed by the pointer. * is the dereference operator. *ptr gets the value at the memory address of ptr *ptr = value; assigns value to memory location of address of ptr Example int x = 10; int *p; // or int* p; int*p; p = &x; // p is now holding the address of variable x, pointing to x int b = *p; // *p is the dereference of p, that gets the value stored in memory location pointed by p. Now b has value 10. *p = 20; // set value 20 to memory location pointed by p, // point to x, so x is now having value 20. Example int *p; *p = 10; // this is not correct, because p does not point to any valid address #include int main() { int x = 1890259661; int *ptr = &x; printf("Value of x is %d\n", x); printf("Runtime memory address of x is %lu\n", (unsigned long int) &x); printf("Value of pointer ptr is %lu\n", (unsigned long int) ptr); printf("Size of pointer ptr is %d\n", sizeof(ptr)); printf("Runtime memory address of pointer ptr is %lu\n", (unsigned long int) &ptr); printf("Value of *ptr is %d\n", *ptr); *ptr = 10; printf("Value of *ptr is %d\n", *ptr); printf("Value of x is %d\n", x); return 0; } Value of x is 1890259661 Runtime memory address of x is 6684316 Value of pointer ptr is 6684316 Size of pointer ptr is 4 Runtime memory address of pointer ptr is 6684312 Value of *ptr is 1890259661 Value of *ptr is 10 Value of x is 10 1890259661 | 10 = 01110000 10101011 00010010 11001101 | 2 6684316 | 10 = 00000000 01100101 11111110 10011100 | 2 memory block of x x’s value is 1890259661 Pointer is a tool to access data Variable Pointer int x = 10; int *p; p is declared to be an int pointer &x represents address of x p = &x; p holds address of x x represents the value stored at *p represents the value stored at p, i.e. x &x int b = *p; b will have value 10. *p = 20; x will have value 20. 1. Pointers provide an alternative method to access memory block and the value stored at the memory block. 2. Pointers make it possible to do address operations, so as to access data for data operations. 3. The values (i.e. address values) of pointers are meaningful only at runtime. 2. Pointer operations 1. Deference operation int num1=2, num2= 3, sum=0, mul=0, div=1; int *ptr1, *ptr2; ptr1 = &num1; ptr2 = &num2; sum = *ptr1 + *ptr2; // the value of sum is ? mul = sum**ptr1; // the value of mul is ? 2. Comparisons Value of a pointer is an address of integer value. We can compare pointers by using relational operators in the expressions. For example, p1 > p2 , p1==p2, p1!=p2 are all valid in C. 3. Add and minus operations Adding/substracting an integer value c to/from a data_type pointer will increase/decrease the address by c * sizef(data_type). Example: int x, *p = &x; p = p + 2; p’s value will be increased by 2*sizeof(int) = 2*4 = 8. e.g. if p’s value is 1000, then after p = p+2; p’s value becomes 1008. 4. Increment or decrement operations by ++ and -- operators. p++; p = p + 1; p--; p = p -1; ++ has high precedence than *. The expression *ptr++ is equivalent to *(ptr++). 3. Special pointers A null pointer (null pointer value) is the special pointer value 0, means not pointing to anywhere. To declare a null pointer you may use the macro NULL (NULL is defined by preprocessor as 0) int *ptr = NULL; // equivalent to int *ptr = 0; In programming, if we don’t want a pointer to point to a memory location, we set it to NULL. Generic Pointers A generic pointer is a pointer that has void as its data type. The generic pointer can be used to point to a variable of any data type. It is declared by syntax: void *ptr; You need to cast a void pointer to the type of pointer before dereferencing of a void pointer. Example, int a = 10; void *ptr = &a; // ptr is declared to be void pointer printf("%d", *(int *) ptr); // (int *) casts ptr to int pointer Generic pointers are used when a pointer has to point to different types of variables at different positions of a program. Pointer to pointer A pointer to pointer is a pointer pointing to a pointer of the same type. To declare a pointer to pointer just add an asterisk (*) to a pointer. Example int x=10; int *p, **pp, ***ppp; p=&x; // p points to x pp=&p; // pp points to p ppp=&pp; // ppp points to pp printf(“%d”, **pp); // This outputs 10. printf(“%d”, ***ppp); // This outputs 10. #include int main() { int x = 10, *ptr, **pptr; ptr = &x; pptr = &ptr; printf("Value of x is %d\n", x); printf("Address of x in Hex is %p\n",&x); printf("Address of x in decimal is %lu\n", &x); printf("Value of pointer variable ptr is %p (address in Hex)\n", ptr); printf("Address of pointer variable ptr is %lu\n", &ptr); printf("The value pointed by Ptr is %d\n",*ptr); printf("Address of pointer pptr is %lu\n", &pptr); printf("The value pointed by pptr is %lu\n", *pptr); printf("The pointed by pptr is %d or %d\n", **pptr, *(*pptr)); return 0; } Value of x is 10 Address of x in Hex is 0061FF0C Address of x in decimal is 6422284 Value of pointer variable ptr is 0061FF0C (address in Hex) Address of pointer variable ptr is 6422280 The value pointed by Ptr is 10 Address of pointer pptr is 6422276 The value pointed by pptr is 6422284 The pointed by pptr is 10 or 10 Function type pointer int max(int x, int b) { return x y? x:y; void process(int, int, int (*)()); } int main() { int min(int x, int y) { int (*p)(), a=2, b=3, c; return x < y? x:y; p = max; } c = (*p)(a,b); printf("Max is %d\n", c); // Max is 3 void process(int x, int y, int (*fun)()) { int result = (*fun)(x, y); process(a, b, max); // 3 printf("%d", result); printf("\n"); } process(a, b, min); // 2 printf("\n"); return 0; } 4. Applications of pointers 1. Pointers are used in pass-by-references. This enables to input/output multiple values to/from a function through function arguments. 2. Pointer increases the efficiency of accessing data for algorithms. 3. Pointers are used in dynamic memory allocation and management. 4. Pointers are used to implement complex data structures like linked lists, queues, stacks, trees. 5. Memory allocations in C 1. Static memory allocation: memory allocation done by declaration of global or static variables. At compile time, a global or static variable is allocated a memory block with a relative address to the data region. At runtime, the statically allocated memory blocks are instanced with absolute addresses in the data region. The size of the data region is determined by the sum of the sizes of statically allocated memory blocks at compile time, it won’t be changed and released at runtime. 2. Automatic memory allocation: the memory allocation done by function arguments and local variables. At compile time, a local or argument variable is assigned a memory block with a relative address to the function scope. At runtime, when the function is called, the memory blocks local variables are allocated in stack region, and automatically released after the function call is finished. By release we mean that the space of the memory block can be reused by follow-up function calls. The automatic release means that the memory release is managed by program execution mechanism, not by program statements. 3. Dynamic memory allocation: the memory allocation done by stdlib library function malloc(). – The memory block of a dynamic allocation is located in the heap region, and it won’t be released automatically after the calling function finishes. – Dynamically allocated memory blocks can be shared by different functions. – When a dynamically allocated memory block is not used anymore, it needs to use free() function to release a memory block. malloc(size) returns the address of memory block of allocated memory block. It returns 0 if allocation fails. Example int *p = (int*) malloc (sizeof(int)); *p = 3; printf("%d", *p); // output 3 free(p); // release the memory block pointed by p Concepts of memory leaking: memory leaking is the situation of loosing the address of dynamically allocated space. Memory leaking example: int *p = (int*) malloc (sizeof(int)); *p = 3; printf("%d", *p); p = NULL; // this causes a memory leaking, free(p); p=NULL; // no memory leaking