0% found this document useful (0 votes)
55 views1 page

Pointers in C PDF

Uploaded by

omkar.ptl556
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views1 page

Pointers in C PDF

Uploaded by

omkar.ptl556
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

Pointers in C

Thursday, 29 August 2024 10:59 AM

https://www.geeksforgeeks.org/c-pointers/

What is a Pointer in C?
A pointer is defined as a derived data type that can store the address of other C variables or a
memory location. We can access and manipulate the data stored in that memory location using
pointers.
As the pointers in C store the memory addresses, their size is independent of the type of data they
are pointing to. This size of pointers in C only depends on the system architecture.

Syntax of C Pointers
The syntax of pointers is similar to the variable declaration in C, but we use the ( * ) dereferencing
operator in the pointer declaration.
datatype * ptr;
where
• ptr is the name of the pointer.
• datatype is the type of data it is pointing to.
The above syntax is used to define a pointer to a variable. We can also define pointers to functions,
structures, etc.

How to Use Pointers?


The use of pointers in C can be divided into three steps:

1. Pointer Declaration
2. Pointer Initialization
3. Pointer Dereferencing

1. Pointer Declaration

In pointer declaration, we only declare the pointer but do not initialize it. To declare a pointer, we
use the ( * ) dereference operator before its name.
Example
int *ptr;
The pointer declared here will point to some random memory address as it is not initialized. Such
pointers are called wild pointers.

2. Pointer Initialization

Pointer initialization is the process where we assign some initial value to the pointer variable. We
generally use the ( &: ampersand ) addressof operator to get the memory address of a variable and
then store it in the pointer variable.

Example
int var = 10;
int * ptr;
ptr = &var;
We can also declare and initialize the pointer in a single step. This method is called pointer
definition as the pointer is declared and initialized at the same time.
Example
int *ptr = &var;
Note: It is recommended that the pointers should always be initialized to some value before starting
using it. Otherwise, it may lead to number of errors.

3. Pointer Dereferencing

Dereferencing a pointer is the process of accessing the value stored in the memory address
specified in the pointer. We use the same ( * ) dereferencing operatorthat we used in the pointer
declaration.

Types of Pointers in C
Pointers in C can be classified into many different types based on the parameter on
which we are defining their types. If we consider the type of variable stored in the
memory location pointed by the pointer, then the pointers can be classified into the
following types:

1. Integer Pointers

As the name suggests, these are the pointers that point to the integer values.
Syntax
int *ptr;

These pointers are pronounced as Pointer to Integer.


Similarly, a pointer can point to any primitive data type. It can point also point to
derived data types such as arrays and user-defined data types such as structures.

2. Pointer to Array

Here:

• data_type is the type of data that the array holds.


• var_name is the name of the pointer variable.
• size_of_array is the size of the array to which the pointer will point.
Example
int (*ptr)[10];
Here ptr is pointer that can point to an array of 10 integers. Since subscript have higher
precedence than indirection, it is necessary to enclose the indirection operator and
pointer name inside parentheses. Here the type of ptr is ‘pointer to an array of 10
integers.

Note: The pointer that points to the 0th element of array and the pointer that points to
the whole array are totally different. The following program shows this

Here, p is pointer to 0th element of the array arr, while ptr is a pointer that points to
the whole array arr.
• The base type of p is int while base type of ptr is ‘an array of 5 integers’.
• We know that the pointer arithmetic is performed relative to the base size, so if we
write ptr++, then the pointer ptr will be shifted forward by 20 bytes.
The following figure shows the pointer p and ptr. The darker arrow denotes a pointer
to an array.

On dereferencing a pointer expression we get a value pointed to by that pointer


expression. The pointer to an array points to an array, so on dereferencing it, we should
get the array, and the name of the array denotes the base address. So whenever a
pointer to an array is dereferenced, we get the base address of the array to which it
points.

Pointer to Multidimensional Arrays

1. Pointers and Two-Dimensional Arrays

In a two-dimensional array, we can access each element by using two subscripts,


where the first subscript represents the row number and the second subscript
represents the column number. The elements of 2-D array can be accessed with the
help of pointer notation also. Suppose arr is a 2-D array, we can access any
element arr[i][j] of the array using the pointer expression *(*(arr + i) + j). Now we’ll see
how this expression can be derived.
Let us take a two dimensional array arr[3][4]:
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };

Since memory in a computer is organized linearly it is not possible to store the 2-D
array in rows and columns. The concept of rows and columns is only theoretical,
actually, a 2-D array is stored in row-major order i.e rows are placed next to each
other. The following figure shows how the above 2-D array will be stored in memory

Each row can be considered as a 1-D array, so a two-dimensional array can be


considered as a collection of one-dimensional arrays that are placed one after another.
In other words, we can say that 2-D dimensional arrays that are placed one after
another. So here arr is an array of 3 elements where each element is a 1-D array of 4
integers.

We know that the name of an array is a constant pointer that points to 0th 1-D array
and contains address 5000. Since arr is a ‘pointer to an array of 4 integers’, according
to pointer arithmetic the expression arr + 1 will represent the address 5016 and
expression arr + 2 will represent address 5032.
So we can say that arr points to the 0th 1-D array, arr + 1points to the 1st 1-D array
and arr + 2 points to the 2nd1-D array.

• Since arr + i points to ith element of arr, on dereferencing it will get ith element
of arr which is of course a 1-D array. Thus the expression *(arr + i)gives us the base
address of ith 1-D array.
• We know, the pointer expression *(arr + i) is equivalent to the subscript
expression arr[i]. So *(arr + i) which is same as arr[i] gives us the base address of ith 1-
D array.
• To access an individual element of our 2-D array, we should be able to access any
jth element of ith 1-D array.
• Since the base type of *(arr + i) is int and it contains the address of 0th element of
ith 1-D array, we can get the addresses of subsequent elements in the ith 1-D array by
adding integer values to *(arr + i).
• For example *(arr + i) + 1 will represent the address of 1st element of 1stelement of
ith 1-D array and *(arr+i)+2 will represent the address of 2nd element of ith 1-D array.
• Similarly *(arr + i) + j will represent the address of jthelement of ith 1-D array. On
dereferencing this expression we can get the jth element of the ith 1-D array.

Pointers and Three Dimensional Arrays

int arr[2][3][2] = { {{5, 10}, {6, 11}, {7, 12}}, {{20, 30}, {21, 31},
{22, 32}} };
In a three dimensional array we can access each element by using three subscripts. Let
us take a 3-D array- We can consider a three dimensional array to be an array of 2-D
array i.e each element of a 3-D array is considered to be a 2-D array. The 3-D
array arr can be considered as an array consisting of two elements where each
element is a 2-D array. The name of the array arr is a pointer to the 0th 2-D array.

Thus the pointer expression *(*(*(arr + i ) + j ) + k) is equivalent to the subscript


expression arr[i][j][k].

We know the expression *(arr + i) is equivalent to arr[i] and the expression *(*(arr + i) +
j) is equivalent arr[i][j]. So we can say that arr[i] represents the base address of ith 2-D
array and arr[i][j] represents the base address of the jth 1-D array.
Example

The below example demonstrates the program to print elements of 3D array using
pointers.

3. Pointer to structure

A structure pointer is defined as the pointer which points to the address of the memory
block that stores a structure known as the structure pointer. Complex data structures
like Linked lists, trees, graphs, etc. are created with the help of structure pointers. The
structure pointer tells the address of a structure in memory by pointing the variable to
the structure variable.

Example:

// C program to demonstrate structure pointer


#include <stdio.h>

struct point {
int value;
};

int main()
{

struct point s;

// Initialization of the structure pointer


struct point* ptr = &s;

return 0;
}
In the above code s is an instance of struct point and ptr is the struct pointer because it
is storing the address of struct point.

Accessing the Structure Member with the Help of Pointers

There are two ways to access the members of the structure with the help of a structure
pointer:
1. With the help of (*) asterisk or indirection operator and (.) dot operator.
2. With the help of ( -> ) Arrow operator.
Below is the program to access the structure members using the structure pointer with
the help of the dot operator.

// C Program to demonstrate Structure pointer


#include <stdio.h>
#include <string.h>

struct Student {
int roll_no;
char name[30];
char branch[40];
int batch;
};

int main()
{

struct Student s1;


struct Student* ptr = &s1;

s1.roll_no = 27;
strcpy(s1.name, "Kamlesh Joshi");
strcpy(s1.branch, "Computer Science And Engineering");
s1.batch = 2019;

printf("Roll Number: %d\n", (*ptr).roll_no);


printf("Name: %s\n", (*ptr).name);
printf("Branch: %s\n", (*ptr).branch);
printf("Batch: %d", (*ptr).batch);

return 0;
}
Output:
1

Below is the program to access the structure members using the structure pointer with
the help of the Arrow operator. In this program, we have created a Structure Student
containing structure variable s. The Structure Student has roll_no, name, branch, and
batch.

// C Program to demonstrate Structure pointer


#include <stdio.h>
#include <string.h>

// Creating Structure Student


struct Student {
int roll_no;
char name[30];
char branch[40];
int batch;
};

// variable of structure with pointer defined


struct Student s, *ptr;

int main()
{

ptr = &s;
// Taking inputs
printf("Enter the Roll Number of Student\n");
scanf("%d", &ptr->roll_no);
printf("Enter Name of Student\n");
scanf("%s", &ptr->name);
printf("Enter Branch of Student\n");
scanf("%s", &ptr->branch);
printf("Enter batch of Student\n");
scanf("%d", &ptr->batch);

// Displaying details of the student


printf("\nStudent details are: \n");

printf("Roll No: %d\n", ptr->roll_no);


printf("Name: %s\n", ptr->name);
printf("Branch: %s\n", ptr->branch);
printf("Batch: %d\n", ptr->batch);

return 0;
}
Output:
Enter the Roll Number of Student
27
Enter Name of Student
Kamlesh_Joshi
Enter Branch of Student
Computer_Science_And_Engineering
Enter batch of Student
2019
Student details are:
Roll No: 27
Name: Kamlesh_Joshi
Branch: Computer_Science_And_Engineering
Batch: 2019

4. Function pointer
In C, like normal data pointers (int *, char *, etc), we can have pointers to functions.
Following is a simple example that shows declaration and function call using function
pointer.

#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a) { printf("Value of a is %d\n", a); }
int main()
{
// fun_ptr is a pointer to function fun()
void (*fun_ptr)(int) = &fun;
/* The above line is equivalent of following two
void (*fun_ptr)(int);
fun_ptr = &fun;
*/
// Invoking fun() using fun_ptr
(*fun_ptr)(10);
return 0;
}
Output
Value of a is 10
Why do we need an extra bracket around function pointers like fun_ptr in above
example?
If we remove bracket, then the expression “void (*fun_ptr)(int)” becomes “void
*fun_ptr(int)” which is declaration of a function that returns void pointer. See following
post for details.

How to declare a pointer to a function?

Following are some interesting facts about function pointers.

1) Unlike normal pointers, a function pointer points to code, not data. Typically a
function pointer stores the start of executable code.

2) Unlike normal pointers, we do not allocate de-allocate memory using function


pointers.

3) A function’s name can also be used to get functions’ address. For example, in the
below program, we have removed address operator ‘&’ in assignment. We have also
changed function call by removing *, the program still works.

#include <stdio.h>
// A normal function with an int parameter
// and void return type
void fun(int a) { printf("Value of a is %d\n", a); }
int main()
{
void (*fun_ptr)(int) = fun; // & removed
fun_ptr(10); // * removed
return 0;
}
Output
Value of a is 10

4) Like normal pointers, we can have an array of function pointers. Below example in
point 5 shows syntax for array of pointers.

5) Function pointer can be used in place of switch case. For example, in below
program, user is asked for a choice between 0 and 2 to do different tasks.

#include <stdio.h>
void add(int a, int b)
{
printf("Addition is %d\n", a + b);
}
void subtract(int a, int b)
{
printf("Subtraction is %d\n", a - b);
}
void multiply(int a, int b)
{
printf("Multiplication is %d\n", a * b);
}
int main()
{
// fun_ptr_arr is an array of function pointers
void (*fun_ptr_arr[])(int, int)
= { add, subtract, multiply };
unsigned int ch, a = 15, b = 10;
printf("Enter Choice: 0 for add, 1 for subtract and 2 "
"for multiply\n");
scanf("%d", &ch);
if (ch > 2)
return 0;
(*fun_ptr_arr[ch])(a, b);
return 0;
}

Output
Enter Choice: 0 for add, 1 for subtract and 2 for multiply
2
Multiplication is 150
6) Like normal data pointers, a function pointer can be passed as an argument and can
also be returned from a function.
For example, consider the following C program where wrapper() receives a void fun()
as parameter and calls the passed function.

// A simple C program to show function pointers as parameter


#include <stdio.h>
// Two simple functions
void fun1() { printf("Fun1\n"); }
void fun2() { printf("Fun2\n"); }
// A function that receives a simple function
// as parameter and calls the function
void wrapper(void (*fun)()) { fun(); }
int main()
{
wrapper(fun1);
wrapper(fun2);
return 0;
}
Output
Fun1
Fun2
This point in particular is very useful in C. In C, we can use function pointers to avoid
code redundancy. For example a simple qsort() function can be used to sort arrays in
ascending order or descending or by any other order in case of array of structures. Not
only this, with function pointers and void pointers, it is possible to use qsort for any
data type.

// An example for qsort and comparator


#include <stdio.h>
#include <stdlib.h>
// A sample comparator function that is used
// for sorting an integer array in ascending order.
// To sort any array for any other data type and/or
// criteria, all we need to do is write more compare
// functions. And we can use the same qsort()
int compare(const void* a, const void* b)
{
return (*(int*)a - *(int*)b);
}
int main()
{
int arr[] = { 10, 5, 15, 12, 90, 80 };
int n = sizeof(arr) / sizeof(arr[0]), i;
qsort(arr, n, sizeof(int), compare);
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}
Output
5 10 12 15 80 90
Similar to qsort(), we can write our own functions that can be used for any data type
and can do different tasks without code redundancy. Below is an example search
function that can be used for any data type. In fact we can use this search function to
find close elements (below a threshold) by writing a customized compare function.

#include <stdbool.h>
#include <stdio.h>
// A compare function that is used for searching an integer
// array
bool compare(const void* a, const void* b)
{
return (*(int*)a == *(int*)b);
}
// General purpose search() function that can be used
// for searching an element *x in an array arr[] of
// arr_size. Note that void pointers are used so that
// the function can be called by passing a pointer of
// any type. ele_size is size of an array element
int search(void* arr, int arr_size, int ele_size, void* x,
bool compare(const void*, const void*))
{
// Since char takes one byte, we can use char pointer
// for any type/ To get pointer arithmetic correct,
// we need to multiply index with size of an array
// element ele_size
char* ptr = (char*)arr;
int i;
for (i = 0; i < arr_size; i++)
if (compare(ptr + i * ele_size, x))
return i;
// If element not found
return -1;
}
int main()
{
int arr[] = { 2, 5, 7, 90, 70 };
int n = sizeof(arr) / sizeof(arr[0]);
int x = 7;
printf("Returned index is %d ",
search(arr, n, sizeof(int), &x, compare));
return 0;
}
Output
Returned index is 2
The above search function can be used for any data type by writing a separate
customized compare().

5. Double pointer
The pointer to a pointer in C is used when we want to store the address of
another pointer. The first pointer is used to store the address of the variable. And
the second pointer is used to store the address of the first pointer. That is why
they are also known as double-pointers. We can use a pointer to a pointer to
change the values of normal pointers or create a variable-sized 2-D array. A
double pointer occupies the same amount of space in the memory stack as a
normal pointer.

Declaration of Pointer to a Pointer in C


Declaring Pointer to Pointer is similar to declaring a pointer in C. The difference is
we have to place an additional ‘*’ before the name of the pointer.
data_type_of_pointer **name_of_variable = & normal_pointer_variable;
int val = 5;
int *ptr = &val; // storing address of val to pointer ptr.
int **d_ptr = &ptr; // pointer to a pointer declared
// which is pointing to an integer.

The above diagram shows the memory representation of a pointer to a pointer.


The first pointer ptr1 stores the address of the variable and the second pointer
ptr2 stores the address of the first pointer.
Example of Double Pointer in C

// C program to demonstrate pointer to pointer


#include <stdio.h>

int main()
{
int var = 789;

// pointer for var


int* ptr2;

// double pointer for ptr2


int** ptr1;

// storing address of var in ptr2


ptr2 = &var;

// Storing address of ptr2 in ptr1


ptr1 = &ptr2;

// Displaying value of var using


// both single and double pointers
printf("Value of var = %d\n", var);
printf("Value of var using single pointer = %d\n", *ptr2);
printf("Value of var using double pointer = %d\n", **ptr1);

return 0;
}
Output
Value of var = 789
Value of var using single pointer = 789
Value of var using double pointer = 789
How Double Pointer Works?

The working of the double-pointer can be explained using the above image:
• The double pointer is declared using the syntax shown above.
• After that, we store the address of another pointer as the value of this new
double pointer.
• Now, if we want to manipulate or dereference to any of its levels, we have to use
Asterisk ( * ) operator the number of times down the level we want to go.
Size of Pointer to Pointer in C
In the C programming language, a double pointer behaves similarly to a normal
pointer in C. So, the size of the double-pointer variable is always equal to the
normal pointers. We can verify this using the below C Program.

Example 1: C Program to find the size of a pointer to a pointer.

// C program to find the size of pointer to pointer


#include <stdio.h>

int main()
{
// defining single and double pointers
int a = 5;
int* ptr = &a;
int** d_ptr = &ptr;

// size of single pointer


printf(" Size of normal Pointer: %d \n", sizeof(ptr));

// size of double pointer


printf(" Size of Double Pointer: %d \n", sizeof(d_ptr));

return 0;
}
Output
Size of normal Pointer: 8
Size of Double Pointer: 8
Note: The output of the above code also depends on the type of machine which is
being used. The size of a pointer is not fixed in the C programming language and
it depends on other factors like CPU architecture and OS used. Usually, for a 64-
bit Operating System, the size will be 8 bytes and for a 32-bit Operating system,
the size will be 4 bytes.

Application of Double Pointers in C


Following are the main uses of pointer to pointers in C:

• They are used in the dynamic memory allocation of multidimensional arrays.


• They can be used to store multilevel data such as the text document paragraph,
sentences, and word semantics.
• They are used in data structures to directly manipulate the address of the nodes
without copying.
• They can be used as function arguments to manipulate the address stored in the
local pointer.
Multilevel Pointers in C
Double Pointers are not the only multilevel pointers supported by the C language.
What if we want to change the value of a double pointer?
In this case, we can use a triple pointer, which will be a pointer to a pointer to a
pointer i.e, int ***t_ptr.

Syntax of Triple Pointer

pointer_type *** pointer_name;


Similarly, to change the value of a triple pointer we can use a pointer to a pointer
to a pointer to a pointer (Four level Pointer). In other words, we can say that to
change the value of a ” level – x ” variable we can use a ” level – x+1 ” pointer.
And this concept can be extended further.

Note: We can use any level pointer in C. There is no restriction about it but it
makes the program very complex and vulnerable to errors.
6. Null pointer

The Null Pointer is the pointer that does not point to any location but NULL. According
to C11 standard:
“An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant. If a null pointer constant is converted to a
pointer type, the resulting pointer, called a null pointer, is guaranteed to compare
unequal to a pointer to any object or function.”

Syntax of Null Pointer Declaration in C


type pointer_name = NULL;
type pointer_name = 0;
We just have to assign the NULL value. Strictly speaking, NULL expands to an
implementation-defined null pointer constant which is defined in many header files
such as “stdio.h”, “stddef.h”, “stdlib.h” etc.

Uses of NULL Pointer in C


Following are some most common uses of the NULL pointer in C:

1. To initialize a pointer variable when that pointer variable hasn’t been assigned any
valid memory address yet.
2. To check for a null pointer before accessing any pointer variable. By doing so, we can
perform error handling in pointer-related code, e.g., dereference a pointer variable only
if it’s not NULL.
3. To pass a null pointer to a function argument when we don’t want to pass any valid
memory address.
4. A NULL pointer is used in data structures like trees, linked lists, etc. to indicate the end.
Check if the pointer is NULL
It is a valid operation in pointer arithmetic to check whether the pointer is NULL. We
just have to use isequal to operator ( == ) as shown below:
ptr == NULL;
The above equation will be true if the pointer is NULL, otherwise, it will be false.
Examples of NULL Pointer in C

Example 1: C Program to avoid segmentation fault while accessing the value of


pointer using NULL pointer

// C NULL pointer demonstration


#include <stdio.h>

int main()
{
// declaring null pointer
int* ptr = NULL;

// derefencing only if the pointer have any value


if (ptr == NULL) {
printf("Pointer does not point to anything");
}
else {
printf("Value pointed by pointer: %d", *ptr);
}
return 0;
}
Output
Pointer does not point to anything
By specifically mentioning the NULL pointer, the C standard gives a mechanism using
which a C programmer can check whether a given pointer is legitimate or not.

6. Void pointer

A void pointer is a pointer that has no associated data type with it. A void pointer can
hold an address of any type and can be typecasted to any type.

Example of Void Pointer in C

// C Program to demonstrate that a void pointer


// can hold the address of any type-castable type

#include <stdio.h>
int main()
{
int a = 10;
char b = 'x';

// void pointer holds address of int 'a'


void* p = &a;
// void pointer holds address of char 'b'
p = &b;
}
Time Complexity: O(1)

Auxiliary Space: O(1)

Properties of Void Pointers

1. void pointers cannot be dereferenced.


Example

The following program doesn’t compile.

// C Program to demonstrate that a void pointer


// cannot be dereferenced

#include <stdio.h>
int main()
{
int a = 10;
void* ptr = &a;
printf("%d", *ptr);

return 0;
}
Output
Compiler Error: 'void*' is not a pointer-to-object type
The below program demonstrates the usage of a void pointer to store the address of
an integer variable and the void pointer is typecasted to an integer pointer and then
dereferenced to access the value. The following program compiles and runs fine.

// C program to dereference the void


// pointer to access the value

#include <stdio.h>

int main()
{
int a = 10;
void* ptr = &a;
// The void pointer 'ptr' is cast to an integer pointer
// using '(int*)ptr' Then, the value is dereferenced
// with `*(int*)ptr` to get the value at that memory
// location
printf("%d", *(int*)ptr);
return 0;
}
Output
10
Time Complexity: O(1)
Auxiliary Space: O(1)

2. The C standard doesn’t allow pointer arithmetic with void pointers. However, in
GNU C it is allowed by considering the size of the void as 1.
Example

The below C program demonstrates the usage of a void pointer to perform pointer
arithmetic and access a specific memory location. The following program compiles and
runs fine in gcc.

// C program to demonstrate the usage


// of a void pointer to perform pointer
// arithmetic and access a specific memory location

#include <stdio.h>

int main()
{
// Declare and initialize an integer array 'a' with two
// elements
int a[2] = { 1, 2 };
// Declare a void pointer and assign the address of
// array 'a' to it
void* ptr = &a;

// Increment the pointer by the size of an integer


ptr = ptr + sizeof(int);

// The void pointer 'ptr' is cast to an integer


// pointer using '(int*)ptr' Then, the value is
// dereferenced with `*(int*)ptr` to get the value at
// that memory location
printf("%d", *(int*)ptr);

return 0;
}
Output
2
Time Complexity: O(1)
Auxiliary Space: O(1)

Note: The above program may not work in other compilers.

7. Wilid pointer

Uninitialized pointers are known as wild pointers because they point to some arbitrary
memory location and may cause a program to crash or behave unexpectedly.

Example of Wild Pointers

In the below code, p is a wild pointer.

// C program that demonstrated wild pointers


int main()
{
/* wild pointer */
int* p;
/* Some unknown memory location is being corrupted.
This should never be done. */
*p = 12;
}

How can we avoid wild pointers?

If a pointer points to a known variable then it’s not a wild pointer.


Example

In the below program, p is a wild pointer till this points to a.

int main()
{
int* p; /* wild pointer */
int a = 10;
/* p is not a wild pointer now*/
p = &a;
/* This is fine. Value of a is changed */
*p = 12;
}
If we want a pointer to a value (or set of values) without having a variable for the
value, we should explicitly allocate memory and put the value in the allocated
memory.

Example

int main()
{
int* p = (int*)malloc(sizeof(int));
// This is fine (assuming malloc doesn't return
// NULL)
*p = 12;
}

8. Constant Pointers

In constant pointers, the memory address stored inside the pointer is constant and
cannot be modified once it is defined. It will always point to the same memory address.
Syntax
data_type * const pointer_name;

9. Pointer to Constant

The pointers pointing to a constant value that cannot be modified are called pointers to
a constant. Here we can only access the data pointed by the pointer, but cannot modify
it. Although, we can change the address stored in the pointer to constant.
Syntax
const data_type * pointer_name;

10. Dangling pointer

A pointer pointing to a memory location that has been deleted (or freed) is called a
dangling pointer. Such a situation can lead to unexpected behavior in the program and
also serve as a source of bugs in C programs.
There are three different ways where a pointer acts as a dangling pointer:

1. De-allocation of Memory

When a memory pointed by a pointer is deallocated the pointer becomes a dangling


pointer.
Example

The below program demonstrates the deallocation of a memory pointed by ptr.


C

// C program to demonstrate Deallocating a memory pointed by


// ptr causes dangling pointer
#include <stdio.h>
#include <stdlib.h>

int main()
{
int* ptr = (int*)malloc(sizeof(int));

// After below free call, ptr becomes a dangling pointer


free(ptr);
printf("Memory freed\n");

// removing Dangling Pointer


ptr = NULL;

return 0;
}
Output
Memory freed

2. Function Call

When the local variable is not static and the function returns a pointer to that local
variable. The pointer pointing to the local variable becomes dangling pointer.

Example
The below example demonstrates a dangling pointer when the local variable is not
static.

// C program to demonstrate the pointer pointing to local


// variable becomes dangling when local variable is not
// static.
#include <stdio.h>

int* fun()
{
// x is local variable and goes out of
// scope after an execution of fun() is
// over.
int x = 5;

return &x;
}

// Driver Code
int main()
{
int* p = fun();
fflush(stdin);

// p points to something which is not


// valid anymore
printf("%d", *p);
return 0;
}
Output
0
In the above example, p becomes dangling as the local variable (x) is destroyed as
soon as the value is returned by the pointer. This can be solved by declaring the
variable x as a static variable as shown in the below example.

// The pointer pointing to local variable doesn't


// become dangling when local variable is static.
#include <stdio.h>

int* fun()
{
// x now has scope throughout the program
static int x = 5;

return &x;
}

int main()
{
int* p = fun();
fflush(stdin);

// Not a dangling pointer as it points


// to static variable.
printf("%d", *p);
}
Output
5

3. Variable Goes Out of Scope

When a variable goes out of scope the pointer pointing to that variable becomes a
dangling pointer.
Example

// C program to demonstrate dangling pointer when variable


// goes put of scope
#include <stdio.h>
#include <stdlib.h>

// driver code
int main()
{
int* ptr;
// creating a block
{
int a = 10;
ptr = &a;
}

// ptr here becomes dangling pointer


printf("%d", *ptr);

return 0;
}
Output
2355224

# important

The size of the pointers in C is equal for every pointer type. The size of the pointer does
not depend on the type it is pointing to. It only depends on the operating system and
CPU architecture. The size of pointers in C is
• 8 bytes for a 64-bit System
• 4 bytes for a 32-bit System
The reason for the same size is that the pointers store the memory addresses, no
matter what type they are. As the space required to store the addresses of the
different memory locations is the same, the memory required by one pointer type will
be equal to the memory required by other pointer types.

The type declaration is needed in the pointer for dereferencing and pointer
arithmetic purposes.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy