# The Concept of Pointers in C [TOC] ## I. Introduction to pointers in C #### A. Pointers variables that store address of another variable, e.g. ```c= int a; int *p; p = &a; a = 5; // print p = 204 // print &a = 204 // print a = 5 ``` ![](https://i.imgur.com/7LizFTR.png) #### B. Working with pointers ```c= int a = 10; int *p; p = &a; printf("Address p is %d\n", p); // Address p is 2750832 printf("value at address p is %d bytes\n", *p) // value at address p is 10 printf("size of integer is %d bytes\n", sizeof(int)); // size of integer is bytes printf("Address p+1 is %d\n", p+1); // Address p+1 is 2750836 printf("value at address p+1 is %d\n", *(p+1)) // value at address p+1 is -858993460 ``` #### C. Pointer types, void pointer, pointer arithmetic int - 4 bytes, char - 1 byte, float - 4 bytes ![](https://i.imgur.com/CzDsPhs.png) ```c= int a = 1025; int *p; p = &a; printf("size of integer is %d bytes\n", sizeof(int)); printf("Address = %d, value = %d\n", p, *p); printf("Address = %d, value = %d\n", p+1, *(p+1)); char *p0; p0 = (char*)p; // typecasting printf("size of char is %d bytes\n", sizeof(char)); printf("Address = %d, value = %d\n", p0, *p0); printf("Address = %d, value = %d\n", p0+1, *(p0+1)); // 1025 = 00000000 00000000 00000100 00000001 ``` ![](https://i.imgur.com/qu4devq.png) ```c= #include <stdio.h> int main(void) { int a = 1025; int *p; p = &a; printf("size of integer is %d bytes\n", sizeof(int)); printf("Address = %d, value = %d\n", p, *p); void *p0; p0 = p; printf("Address = %d\n", p0); printf("Address = %d\n", p0+1); return 0; } ``` ![](https://i.imgur.com/yY4QYNp.png) **We can find that void pointer the address of p0+1 is the address of p0 plus 1 byte, but keep in mind, it will fail in some compiler because of compilation error.** #### D. Pointer to pointer ![](https://i.imgur.com/hyfJlnd.png) ```c= int x = 5; int* p = &x; *p = 6; int** q = &p; int*** r = &q; printf("%d\n", *p); // 6 printf("%d\n", *q); // 225 printf("%d\n", *(*q)); // 6 printf("%d\n", *(*r)); // 225 printf("%d\n", *(*(*r)); // 6 ``` ![](https://i.imgur.com/f2ba3Xf.png) ## II. Pointers as function arguments - Call by reference ![](https://i.imgur.com/gUscqas.png) We can find that the addresses of a in main and Increment are different, so if you print a in main function, you will see a is equal to 0. First let we review the concept of memory (RAM) in OS. ![](https://i.imgur.com/r6UYn1a.png) ps. If we write a non-stopable recurrsion code, the stack will be overflow. ![](https://i.imgur.com/GKRQjJl.png) We call printf which is a library function ![](https://i.imgur.com/l8CSpoX.png) In the following picture, we can find that a is not a in main(); therefore, this issue is "call by value". ![](https://i.imgur.com/pJZXNoG.png) What is "call by reference"? We can draw only the stack here so that we are able to show the simulation of program execution neatly. ![](https://i.imgur.com/jpjcXVI.png) ## III. Pointer an Arrays #### A. The fundamental concept of array ![](https://i.imgur.com/7TWVeu9.png) notice that A[i] == *(A+i), which is a very important concept in C language ```c= int A[] = {2, 4, 5, 8, 1}; printf("%d\n", A); // 1004606304 printf("%d\n", &A[0]); // 1004606304 printf("%d\n", A[0]); // 2 printf("%d\n", *A); // 2 // We can try the following code, after the above code execution // int A[] = {2, 4, 5, 8, 1}; // int i; // int *p = A; // for (int i = 0; i < 5; i++){ // printf("Address = %d\n", A+i); // printf("Address = %d\n", &A[i]); // printf("value = %d\n", A[i]); // printf("value = %d\n", *(A+i)); // } ``` #### B. Arrays as function arguments ```c= #include <stdio.h> int SumOfElements(int A[]){ int i, sum = 0; int size = sizeof(A) / sizeof(A[0]); printf("SOE - Size of A = %d, size of A[0] = %d\n", sizeof(A), sizeof(A[0])); for (i = 0; i < size; i++){ sum+= A[i]; } return sum; } int main(void) { int A[] = {1, 2, 3, 4, 5}; int total = SumOfElements(A); // A can be used for &A[0] printf("Main - Size of A = %d, size of A[0] = %d\n", sizeof(A), sizeof(A[0])); return 0; } ``` ![](https://i.imgur.com/ud7jj2I.png) Why the size of a is 4 bytes? ![](https://i.imgur.com/shrzKSn.png) The compiler just copies the address of the first elemnet in the array of the calling function. #### C. Character arrays and pointers ##### 1. How to store strings size of array >= number of characters in string + 1 "John" size >= 5 ```c= char C[5] = {'J', 'O', 'H', 'N', '\0'}; printf("Size in bytes = %d\n", sizeof(C)); int len = strlen(C); printf("Length = %d\n", len); // Size in bytes = 5 // Length = 4 ``` ##### 2. Arrays and pointers are different types that are used in similar manner ![](https://i.imgur.com/KrN8xRA.png) ```c= Print C2[1]; // l c2[0] = 'A'; // "Aello" c2[i] is *(c2+i) c1[i] or *(c1+i) ``` * c1 = c2 is false * c1 = c1+1 is false * c2++ is true ##### 3. Arrays are always passed to function by reference ![](https://i.imgur.com/W5AwR3u.png) we also can re-write *C != '\0' C++ ==> *(C+i) != '\0' i++ ## IV. Pointers and multi-dimensional arrays ![](https://i.imgur.com/PtG0A0N.png) #### A. 2-D array What about 2-D array? ![](https://i.imgur.com/bIrXfdh.png) ![](https://i.imgur.com/9yzULhE.png) For 2-D array ```c= B[i][j] = *(B[i]+j) = *(*(B+i) + j) ``` ![](https://i.imgur.com/hlIbIN9.png) ![](https://i.imgur.com/F7Cq6ob.png) #### B. Multi-dimention array ![](https://i.imgur.com/H8VWzLd.png) ![](https://i.imgur.com/HyRc4o8.png) ![](https://i.imgur.com/0TqF5RX.png) ## V. Pointers and dynamic memory #### A. Fundamentals ![](https://i.imgur.com/Enovcx9.png) Notice that Address 200 in heap will be free. More... ![](https://i.imgur.com/sV6ejky.png) ```c= // in C++ int a; int *p; p = new int; *p = 10; delete p; p = new int[20]; delete[] p; ``` #### B. malloc, calloc, realloc, free ![](https://i.imgur.com/GTCP8vi.png) ![](https://i.imgur.com/eaeCZQe.png) ![](https://i.imgur.com/Ro1GExK.png) ```c= printf("Enter size of array\n"); scanf("%d", &n); int* A = (int*)malloc(n*sizeof(int)); // how about (int*)calloc(n, sizeof(int))? it will have a initial value 0, but malloc don't. for (int i = 0; i < n; i+){ A[i] = i+1; } // free(A); // A[2] = 6; // value at address A+2 // A = NULL; // After free, adjust pointer to NULL for (int i = 0; i < n; i++){ printf("%d", A[i]); } ``` What if we want to change the size of A? ![](https://i.imgur.com/s2Kttmw.png) ![](https://i.imgur.com/vywMpQw.png) (int*)realloc(A, 0) == equivalent to free(A) (int*)realloc(NULL, n*sizeof(int)) == equivalent to malloc #### C. Pointers as function returns ![](https://i.imgur.com/I9awvvV.png) ![](https://i.imgur.com/12v1szT.png) #### D. Function Pointers ![](https://i.imgur.com/w1Ae6Gy.png) ![](https://i.imgur.com/ytWzdmL.png) #### E. Function Pointers and callbacks ```c= #include <stdio.h> void A(){ printf("Hello\n"); } void B(void (*ptr)()){ ptr(); } int main(void) { void (*p)() = A; B(p); // or B(A) } ``` ```c= #include <stdio.h> void BubbleSort(int* A, int n){ int i, j, temp; for (i = 0; i < n; i++){ for (j = 0; j < n-1; j++){ if (A[j] > A[j+1]){ temp = A[j]; A[j] = A[j+1]; A[j+1] = temp; } } } } int main(void) { int i, A[] = {3, 2, 1, 5, 6, 4}; BubbleSort(A, 6); for (i = 0; i < 6; i++) printf("%d ", A[i]); } ``` ![](https://i.imgur.com/PiEXbNV.png) ![](https://i.imgur.com/zu0zcu2.png) A - B ==> abs(A) - abs(B) ## VI. What is memory leak ?