Pointers in C - C++
Pointers in C - C++
Table of Contents
1. Must Watch Videos
2. C pointers Document
3. Interesting Pointers Questions
4. Useful Links
[Video Link]
[Video Link]
Consider the following example to define a pointer which stores the address of an
integer.
1. int n = 10;
2. int* p = &n; // Variable p of type pointer is pointing to the address of the variable n of t
ype integer.
Declaring a pointer
The pointer in c language can be declared using * (asterisk symbol). It is also known as
indirection pointer used to dereference a pointer.
Pointer Example
An example of using pointers to print the address and value is given below.
As you can see in the above figure, pointer variable stores the address of number
variable, i.e., fff4. The value of number variable is 50. But the address of pointer variable
p is aaa3.
By the help of * (indirection operator), we can print the value of pointer variable p.
Let's see the pointer example as explained for the above figure.
1. #include<stdio.h>
2. int main(){
8. return 0;
9. }
Output
Pointer to array
1. int arr[10];
2. int *p[10]=&arr; // Variable p of type pointer is pointing to the address of an integer arr
ay arr.
Pointer to a function
Pointer to structure
1. struct st {
2. int i;
3. float f;
4. }ref;
5. struct st *p = &ref;
3) It makes you able to access any memory location in the computer's memory.
Usage of pointer
There are many applications of pointers in c language.
In c language, we can dynamically allocate memory using malloc() and calloc() functions where
the pointer is used.
Pointers in c language are widely used in arrays, functions, and structures. It reduces the
code and improves the performance.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. printf("value of number is %d, address of number is %u",number,&number);
5. return 0;
6. }
Output
NULL Pointer
int *p=NULL;
Output
Data type 3 -
o (): This operator is a bracket operator used to declare and define the function.
o []: This operator is an array subscript operator
o * : This operator is a pointer operator.
o Identifier: It is the name of the pointer. The priority will always be assigned to this.
o Data type: Data type is the type of the variable to which the pointer is intended
to point. It also includes the modifier like signed int, long, etc).
To read the pointer, we must see that () and [] have the equal precedence. Therefore,
their associativity must be considered here. The associativity is left to right, so the
priority goes to ().
Inside the bracket (), pointer operator * and pointer name (identifier) p have the same
precedence. Therefore, their associativity must be considered here which is right to left,
so the priority goes to p, and the second priority goes to *.
Assign the 3rd priority to [] since the data type has the last precedence. Therefore the
pointer will look like following.
o char -> 4
o * -> 2
o p -> 1
o [10] -> 3
Example
1. #include<stdio.h>
2. void main ()
3. {
4. int a = 10;
5. int *p;
6. int **pp;
7. p = &a; // pointer p is pointing to the address of a
8. pp = &p; // pointer pp is a double pointer pointing to the address of pointer p
9. printf("address of a: %x\n",p); // Address of a will be printed
10. printf("address of p: %x\n",pp); // Address of p will be printed
11. printf("value stored at p: %d\n",*p); // value stoted at the address contained by p i.e. 10 will b
e printed
Output
address of a: d26a8734
address of p: d26a8738
value stored at p: 10
value stored at pp: 10
As you can see in the above figure, p2 contains the address of p (fff2), and p contains
the address of number variable (fff4).
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. int **p2;//pointer to pointer
6. p=&number;//stores the address of number variable
7. p2=&p;
8. printf("Address of number variable is %x \n",&number);
9. printf("Address of p variable is %x \n",p);
10. printf("Value of *p variable is %d \n",*p);
11. printf("Address of p2 variable is %x \n",p2);
12. printf("Value of **p2 variable is %d \n",*p);
13. return 0;
14. }
Output
Address of number variable is fff4
Address of p variable is fff4
Value of *p variable is 50
Address of p2 variable is fff2
Value of **p variable is 50
o Increment
o Decrement
o Addition
o Subtraction
o Comparison
Incrementing Pointer in C
If we increment a pointer by 1, the pointer will start pointing to the immediate next
location. This is somewhat different from the general arithmetic since the value of the
pointer will get increased by the size of the data type to which the pointer is pointing.
We can traverse an array by using the increment operation on a pointer which will keep
pointing to every element of the array, perform some operation on that, and update
itself in a loop.
32-bit
For 32-bit int variable, it will be incremented by 2 bytes.
64-bit
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p+1;
8. printf("After increment: Address of p variable is %u \n",p); // in our case, p will get incre
mented by 4 bytes.
9. return 0;
10. }
Output
1. #include<stdio.h>
2. void main ()
3. {
4. int arr[5] = {1, 2, 3, 4, 5};
5. int *p = arr;
6. int i;
7. printf("printing array elements...\n");
8. for(i = 0; i< 5; i++)
9. {
10. printf("%d ",*(p+i));
11. }
12. }
Output
Decrementing Pointer in C
Like increment, we can decrement a pointer variable. If we decrement a pointer, it will
start pointing to the previous location. The formula of decrementing the pointer is given
below:
32-bit
For 32-bit int variable, it will be decremented by 2 bytes.
64-bit
For 64-bit int variable, it will be decremented by 4 bytes.
1. #include <stdio.h>
2. void main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p-1;
8. printf("After decrement: Address of p variable is %u \n",p); // P will now point to the im
midiate previous location.
9. }
Output
C Pointer Addition
32-bit
For 32-bit int variable, it will add 2 * number.
64-bit
Let's see the example of adding value to pointer variable on 64-bit architecture.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p+3; //adding 3 to pointer variable
8. printf("After adding 3: Address of p variable is %u \n",p);
9. return 0;
10. }
Output
As you can see, the address of p is 3214864300. But after adding 3 with p variable, it is
3214864312, i.e., 4*3=12 increment. Since we are using 64-bit architecture, it increments
12. But if we were using 32-bit architecture, it was incrementing to 6 only, i.e., 2*3=6. As
integer value occupies 2-byte memory in 32-bit OS.
C Pointer Subtraction
32-bit
For 32-bit int variable, it will subtract 2 * number.
64-bit
For 64-bit int variable, it will subtract 4 * number.
Let's see the example of subtracting value from the pointer variable on 64-bit
architecture.
1. #include<stdio.h>
2. int main(){
3. int number=50;
4. int *p;//pointer to int
5. p=&number;//stores the address of number variable
6. printf("Address of p variable is %u \n",p);
7. p=p-3; //subtracting 3 from pointer variable
8. printf("After subtracting 3: Address of p variable is %u \n",p);
9. return 0;
10. }
Output
You can see after subtracting 3 from the pointer variable, it is 12 (4*3) less than the
previous address value.
1. Address2 -
Address1 = (Subtraction of two addresses)/size of data type which pointer points
1. #include<stdio.h>
2. void main ()
3. {
4. int i = 100;
5. int *p = &i;
6. int *temp;
7. temp = p;
8. p = p + 3;
9. printf("Pointer Subtraction: %d - %d = %d",p, temp, p-temp);
10. }
Output
Pointer to function in C
As we discussed in the previous chapter, a pointer can point to a function in C. However,
the declaration of the pointer variable must be the same as the function. Consider the
following example to make a pointer pointing to the function.
1. #include<stdio.h>
2. int addition ();
3. int main ()
4. {
5. int result;
6. int (*ptr)();
7. ptr = &addition;
8. result = (*ptr)();
9. printf("The sum is %d",result);
10. }
11. int addition()
12. {
13. int a, b;
14. printf("Enter two numbers?");
15. scanf("%d %d",&a,&b);
16. return a+b;
17. }
Output
Output
Dangling pointer occurs at the time of the object destruction when the object is deleted
or de-allocated from memory without modifying the value of the pointer. In this case,
the pointer is pointing to the memory, which is de-allocated. The dangling pointer can
point to the memory, which contains either the program code or the code of the
operating system. If we assign the value to this pointer, then it overwrites the value of
the program code or operating system instructions; in such cases, the program will show
the undesirable result or may even crash. If the memory is re-allocated to some other
process, then we dereference the dangling pointer will cause the segmentation faults.
In the above figure, we can observe that the Pointer 3 is a dangling pointer. Pointer
1 and Pointer 2 are the pointers that point to the allocated objects, i.e., Object 1 and
Object 2, respectively. Pointer 3 is a dangling pointer as it points to the de-allocated
object.
1. #include <stdio.h>
In the above code, we have created two variables, i.e., *ptr and a where 'ptr' is a pointer
and 'a' is a integer variable. The *ptr is a pointer variable which is created with the help
of malloc() function. As we know that malloc() function returns void, so we use int * to
convert void pointer into int pointer.
The statement int *ptr=(int *)malloc(sizeof(int)); will allocate the memory with 4 bytes
shown in the below image:
The statement free(ptr) de-allocates the memory as shown in the below image with a
cross sign, and 'ptr' pointer becomes dangling as it is pointing to the de-allocated
memory.
If we assign the NULL value to the 'ptr', then 'ptr' will not point to the deleted memory.
Therefore, we can say that ptr is not a dangling pointer, as shown in the below image:
When the variable goes out of the scope then the pointer pointing to the variable
becomes a dangling pointer.
1. #include<stdio.h>
2. int main()
3. {
4. char *str;
5. {
6. char a = ?A?;
7. str = &a;
8. }
9. // a falls out of scope
10. // str is now a dangling pointer
11. printf("%s", *str);
12. }
Function call
Now, we will see how the pointer becomes dangling when we call the function.
o First, we create the main() function in which we have declared 'p' pointer that
contains the return value of the fun().
o When the fun() is called, then the control moves to the context of the int
*fun(), the fun() returns the address of the 'y' variable.
o When control comes back to the context of the main() function, it means the
variable 'y' is no longer available. Therefore, we can say that the 'p' pointer is a
dangling pointer as it points to the de-allocated memory.
Output
1. #include <stdio.h>
2. int *fun()
3. {
4. static int y=10;
5. return &y;
6. }
7. int main()
8. {
9. int *p=fun();
10. printf("%d", *p);
11. return 0;
12. }
The above code is similar to the previous one but the only difference is that the variable
'y' is static. We know that static variable stores in the global memory.
Output
The above diagram shows the stack memory. First, the fun() function is called, then the
control moves to the context of the int *fun(). As 'y' is a static variable, so it stores in
the global memory; Its scope is available throughout the program. When the address
value is returned, then the control comes back to the context of the main(). The pointer
'p' contains the address of 'y', i.e., 100. When we print the value of '*p', then it prints the
value of 'y', i.e., 10. Therefore, we can say that the pointer 'p' is not a dangling pointer as
it contains the address of the variable which is stored in the global memory.
The dangling pointer errors can be avoided by initializing the pointer to the NULL value.
If we assign the NULL value to the pointer, then the pointer will not point to the de-
allocated memory. Assigning NULL value to the pointer means that the pointer is not
pointing to any memory location.
sizeof() operator in C
1. int *ptr=malloc(10*sizeof(int));
In the above example, we use the sizeof() operator, which is applied to the cast of type
int. We use malloc() function to allocate the memory and returns the pointer which is
pointing to this allocated memory. The memory space is equal to the number of bytes
occupied by the int data type and multiplied by 10.
Note:
The output can vary on different machines such as on 32-bit operating system will show
different output, and the 64-bit operating system will show the different outputs of the same
data types.
The sizeof() operator behaves differently according to the type of the operand.
1. #include <stdio.h>
2. int main()
3. {
4. int x=89; // variable declaration.
5. printf("size of the variable x is %d", sizeof(x)); // Displaying the size of ?x? variable.
6. printf("\nsize of the integer data type is %d",sizeof(int)); //Displaying the size of integer data t
ype.
In the above code, we are printing the size of different data types such as int, char, float
with the help of sizeof() operator.
Output
1. #include <stdio.h>
2. int main()
3. {
4. double i=78.0; //variable initialization.
5. float j=6.78; //variable initialization.
6. printf("size of (i+j) expression is : %d",sizeof(i+j)); //Displaying the size of the expression (i+j).
7. return 0;
8. }
In the above code, we have created two variables 'i' and 'j' of type double and float
respectively, and then we print the size of the expression by using sizeof(i+j) operator.
const Pointer in C
Constant Pointers
A constant pointer in C cannot change the address of the variable to which it is pointing,
i.e., the address will remain constant. Therefore, we can say that if a constant pointer is
pointing to some variable, then it cannot point to any other variable.
1. #include <stdio.h>
2. int main()
3. {
4. int a=1;
5. int b=2;
6. int *const ptr;
7. ptr=&a;
8. ptr=&b;
9. printf("Value of ptr is :%d",*ptr);
10. return 0;
11. }
Output
In the above output, we can observe that the above code produces the error
"assignment of read-only variable 'ptr'". It means that the value of the variable 'ptr'
which 'ptr' is holding cannot be changed. In the above code, we are changing the value
of 'ptr' from &a to &b, which is not possible with constant pointers. Therefore, we can
say that the constant pointer, which points to some variable, cannot point to another
variable.
Pointer to Constant
A pointer to constant is a pointer through which the value of the variable that the
pointer points cannot be changed. The address of these pointers can be changed, but
the value of the variable that the pointer points cannot be changed.
o First, we write the code where we are changing the value of a pointer
1. #include <stdio.h>
2. int main()
3. {
4. int a=100;
5. int b=200;
o We declare two variables, i.e., a and b with the values 100 and 200 respectively.
o We declare a pointer to constant.
o First, we assign the address of variable 'a' to the pointer 'ptr'.
o Then, we assign the address of variable 'b' to the pointer 'ptr'.
o Lastly, we try to print the value of 'ptr'.
Output
The above code runs successfully, and it shows the value of 'ptr' in the output.
o Now, we write the code in which we are changing the value of the variable to
which the pointer points.
1. #include <stdio.h>
2. int main()
3. {
4. int a=100;
5. int b=200;
6. const int* ptr;
7. ptr=&b;
8. *ptr=300;
9. printf("Value of ptr is :%d",*ptr);
o We declare two variables, i.e., 'a' and 'b' with the values 100 and 200 respectively.
o We declare a pointer to constant.
o We assign the address of the variable 'b' to the pointer 'ptr'.
o Then, we try to modify the value of the variable 'b' through the pointer 'ptr'.
o Lastly, we try to print the value of the variable which is pointed by the pointer
'ptr'.
Output
The above code shows the error "assignment of read-only location '*ptr'". This error
means that we cannot change the value of the variable to which the pointer is pointing.
Syntax
o We declare two variables, i.e., 'a' and 'b' with the values 10 and 90, respectively.
o We declare a constant pointer to a constant and then assign the address of 'a'.
o We try to change the value of the variable 'a' through the pointer 'ptr'.
o Then we try to assign the address of variable 'b' to the pointer 'ptr'.
o Lastly, we print the value of the variable, which is pointed by the pointer 'ptr'.
Output
The above code shows the error "assignment of read-only location '*ptr'" and
"assignment of read-only variable 'ptr'". Therefore, we conclude that the constant
void pointer in C
Till now, we have studied that the address assigned to a pointer should be of the same
type as specified in the pointer declaration. For example, if we declare the int pointer,
then this int pointer cannot point to the float variable or some other type of variable,
i.e., it can point to only int type variable. To overcome this problem, we use a pointer to
void. A pointer to void means a generic pointer that can point to any data type. We can
assign the address of any data type to the void pointer, and a void pointer can be
assigned to any type of the pointer without performing any explicit typecasting.
1. void *ptr;
In the above declaration, the void is the type of the pointer, and 'ptr' is the name of the
pointer.
p=fp; // incorrect.
fp=&i; // incorrect
ptr=p; // correct
ptr=fp; // correct
1. #include <stdio.h>
2. int main()
3. {
4. void *ptr = NULL; //void pointer
5. int *p = NULL;// integer pointer
6. char *cp = NULL;//character pointer
7. float *fp = NULL;//float pointer
8. //size of void pointer
9. printf("size of void pointer = %d\n\n",sizeof(ptr));
10. //size of integer pointer
11. printf("size of integer pointer = %d\n\n",sizeof(p));
12. //size of character pointer
13. printf("size of character pointer = %d\n\n",sizeof(cp));
14. //size of float pointer
15. printf("size of float pointer = %d\n\n",sizeof(fp));
16. return 0;
17. }
o The malloc() and calloc() function return the void pointer, so these functions can
be used to allocate the memory of any data type.
1. #include <stdio.h>
2. #include<malloc.h>
3. int main()
4. {
5. int a=90;
6.
7. int *x = (int*)malloc(sizeof(int)) ;
8. x=&a;
9. printf("Value which is pointed by x pointer : %d",*x);
10. return 0;
11. }
Output
The void pointer in C cannot be dereferenced directly. Let's see the below example.
1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. void *ptr;
6. ptr=&a;
7. printf("Value which is pointed by ptr pointer : %d",*ptr);
8. return 0;
9. }
In the above code, *ptr is a void pointer which is pointing to the integer variable 'a'. As
we already know that the void pointer cannot be dereferenced, so the above code will
give the compile-time error because we are printing the value of the variable pointed by
the pointer 'ptr' directly.
Output
1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. void *ptr;
6. ptr=&a;
7. printf("Value which is pointed by ptr pointer : %d",*(int*)ptr);
8. return 0;
9. }
In the above code, we typecast the void pointer to the integer pointer by using the
statement given below:
(int*)ptr;
Then, we print the value of the variable which is pointed by the void pointer 'ptr' by
using the statement given below:
*(int*)ptr;
Output
The above code shows the compile-time error that "invalid use of void expression" as
we cannot apply the arithmetic operations on void pointer directly, i.e., ptr=ptr+1.
1. #include<stdio.h>
2. int main()
3. {
4. float a[4]={6.1,2.3,7.8,9.0};
5. void *ptr;
6. ptr=a;
7. for(int i=0;i<4;i++)
8. {
9. printf("%f,",*((float*)ptr+i));
10. }}
The above code runs successfully as we applied the proper casting to the void pointer,
i.e., (float*)ptr and then we apply the arithmetic operation, i.e., *((float*)ptr+i).
Output
1. #include<stdio.h>
2. int main()
3. {
4. int a=56; // initialization of a integer variable 'a'.
5. float b=4.5; // initialization of a float variable 'b'.
6. char c='k'; // initialization of a char variable 'c'.
7. void *ptr; // declaration of void pointer.
8. // assigning the address of variable 'a'.
9. ptr=&a;
10. printf("value of 'a' is : %d",*((int*)ptr));
11. // assigning the address of variable 'b'.
12. ptr=&b;
13. printf("\nvalue of 'b' is : %f",*((float*)ptr));
14. // assigning the address of variable 'c'.
15. ptr=&c;
16. printf("\nvalue of 'c' is : %c",*((char*)ptr));
17. return 0;
18. }
Output
o It can be used to access or manipulate the data stored at the memory location, which is
pointed by the pointer.
o Any operation applied to the dereferenced pointer will directly affect the value of the
variable that it points to.
1. int x =9;
o Now, we declare the integer pointer variable.
1. int *ptr;
o After the declaration of an integer pointer variable, we store the address of 'x' variable to
the pointer variable 'ptr'.
1. ptr=&x;
o We can change the value of 'x' variable by dereferencing a pointer 'ptr' as given below:
1. *ptr =8;
The above line changes the value of 'x' variable from 9 to 8 because 'ptr' points to the 'x'
location and dereferencing of 'ptr', i.e., *ptr=8 will update the value of x.
Output
1. #include <stdio.h>
2. int main()
3. {
4. int x=4;
5. int y;
6. int *ptr;
7. ptr=&x;
8. y=*ptr;
9. *ptr=5;
10. printf("The value of x is : %d",x);
11. printf("\n The value of y is : %d",y);
12. return 0;
13. }
Note: According to us, if we change the value of 'x', then the value of 'y' will also get
changed as the pointer 'ptr' holds the address of the 'x' variable. But this does not happen,
as 'y' is storing the local copy of value '5'.
Output
1. #include <stdio.h>
2. int main()
3. {
4. int a=90;
5. int *ptr1,*ptr2;
6. ptr1=&a;
7. ptr2=&a;
8. *ptr1=7;
9. *ptr2=6;
10. printf("The value of a is : %d",a);
11. return 0;
12. }
Note: If we have more than one pointer pointing to the same location, then the change
made by one pointer will be the same as another pointer.
Output
Useful Links
1. GeeksforGeeks - C Pointers
2. freeCodeCamp.org - Pointers in C are Not as Difficult as You Think
3. LeetCode - Study Guide: Master in Two Pointer
These links provide valuable information and tutorials on pointers in C programming. They
cover topics such as the fundamentals of pointers, arrays and strings, functions, and more.
Including these links in your PDF will provide additional resources for readers to explore and
deepen their understanding of pointers in C.