# 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
```

#### 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

```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
```

```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;
}
```

**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

```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
```

## II. Pointers as function arguments - Call by reference

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.

ps. If we write a non-stopable recurrsion code, the stack will be overflow.

We call printf which is a library function

In the following picture, we can find that a is not a in main(); therefore, this issue is "call by value".

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.

## III. Pointer an Arrays
#### A. The fundamental concept of array

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;
}
```

Why the size of a is 4 bytes?

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

```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

we also can re-write *C != '\0' C++ ==> *(C+i) != '\0' i++
## IV. Pointers and multi-dimensional arrays

#### A. 2-D array
What about 2-D array?


For 2-D array
```c=
B[i][j] = *(B[i]+j) = *(*(B+i) + j)
```


#### B. Multi-dimention array



## V. Pointers and dynamic memory
#### A. Fundamentals

Notice that Address 200 in heap will be free.
More...

```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



```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?


(int*)realloc(A, 0) == equivalent to free(A)
(int*)realloc(NULL, n*sizeof(int)) == equivalent to malloc
#### C. Pointers as function returns


#### D. Function Pointers


#### 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]);
}
```


A - B ==> abs(A) - abs(B)
## VI. What is memory leak ?