---
# System prepended metadata

title: The Concept of Pointers in C

---

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