0% found this document useful (0 votes)
8 views

Module 1

Uploaded by

Dhanushree AN
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)
8 views

Module 1

Uploaded by

Dhanushree AN
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/ 79

When we use structures?

What is a structure? What is the syntax to define a structure?

Note:

What are the different types of structures?

What is tagged structure? How to define tagged structure?


What is structure declara<on? How to declare structure variables?

How and when memory is allocated for a structure?

How to ini<alize tagged structure?


More than one variable is ini<alized as shown below:

What are the different methods using which structure variables can be defined using
typedef?
How to ini<alize type-defined structure?

How to ini<alize structure variables par<ally?

Is it possible to ini<alize the members without declaring the variables?


Consider the following program segment:
]
Note: The slack bytes are shown using black boxes in the above figure.’
The complete program to read student inform, sort student info and to print student info can be written
as shown below:

Can a structure contain array as a member name?


Yes. Definitely a structure can contain an array as the member name. Consider the following structure.

Note: The members “name” and “marks” are arrays inside the structure “STUDNT”.
How to initialize the members of a structure when structure has array as the member name? A structure
having array as the member can be initialized as shown in program segment below:

How to initialize the structures having arrays as member name? The structure having array name as
member can be initialized as shown below:

The complete program to read the student info, sort the student info and to print the student info can be
written as shown below:
The above function multiply can also be written using array operator as shown below:

How to represent a complex number in C? A complex number 3 + 8i can be represented using structures
as shown below:

The function to read a complex number can be written as:


The function to print a complex number can be written as shown below:

The program to read a complex number, print a complex number and to add two complex numbers can
be written as shown below:

Write a C program to search for given student name in a student record consisting of name and marks

The given student called “key” has to be compared with all records as shown below:

The algorithm and equivalent code can be written as shown below:

The complete C program to search for a given key in an array of student records can be written as shown
below:
Write a program to print student information who got above average marks and who got below average
marks separately.

The structure representation is shown below:

The student record where number of students n = 5 is shown below:

The algorithm to find the average can be written as shown below:

The complete program to print the student info who got more than average marks and who got less than
average is shown below:
How memory is allocated?
How memory is allocated?
Chapter 12: Pointers
What are we studying in this chapter?
¨ Pointers and address
¨ Pointers and function arguments
¨ pointers and arrays, address arithmetic
¨ character pointer and functions
¨ Pointer to pointer , Initialization of pointer arrays
¨ Understanding complex declarations
¨ dynamic allocation methods
¨ Array of pointers and programming examples. - 7 hours

Example 12.1: Program to print the values using variables and their addresses

#include <stdio.h>
void main()
a b
{
int a = 25; 25 45
int b = 45; 1000 1002
/* Accessing the data using variables */
printf(“Value of a = %d\n”, a); Value of a = 25
printf(“Value of b = %d\n”, b); Value of b = 45

/* Accessing the address of variables */


printf(“Address of a = %d\n”, &a); Address of a = 1000
printf(“Address of b = %d\n”, &b); Address of b = 1002
/* Accessing the data using de-referencing operator */
printf(“Value of a = %d\n”, *&a); Value of a = 25
printf(“Value of b = %d\n”, *&b); Value of b = 45
}

Note: Observe that the operator pair *& gets cancelled each other. So,
¨ *&a is same as a
¨ *&b is same as b
Now, the question is “Is it possible to store the address of a variable into memory?”.
Yes, it is possible. As we store the data using assignment operator, we can store
address of variable using assignment operator as shown below:
12.2 : Pointers
p = &a; // Now, the variable p contains address of variable a
x = &b; // Now, the variable x contains address of variable b

Note: Please see that, the variables p and x in above two statements are not normal
variables, as they do not contain the data. Instead the variables p and x contain
addresses of the data. These variables p and x which contain the addresses are
called pointers or pointer variables.
Now, once we know what are pointer variables, the next question is “How to declare
the pointer variables?” It is very simple and can be done as shown below:
If a variable p contains address of int variable its declaration is: int *p;
If a variable x contains address of float variable its declaration is: float *x;
If a variable y contains address of char variable its declaration is: char *y;
If a variable z contains address of double variable its declaration is: double *z;
Note: The address operator can be used with any variable that can be placed on the
left side of an assignment operator. Since constants, expressions and array names
cannot be used on the left hand side of the assignment and hence accessing address is
invalid for constants, expressions and array names. The following are invalid:

Usage Valid/Invalid Reasons for invalidity


&100 Invalid Address of a constant cannot be obtained
&(p + 10) Invalid Address of an expression cannot be obtained
&(p + q) Invalid Address of an expression cannot be obtained
int a[10];
Invalid Address of entire array cannot be obtained
&a
register a;
Invalid Address of a register variable cannot be
&a
obtained
Now, formally a pointer can be defined as shown below:
Definition: A variable that contains the address of another variable or address of a
memory location is called a pointer. A pointer is also called a pointer variable.
Once we know the concept of pointers, let us see “What are the steps to be followed
to use pointers?” The following sequence of steps have to be followed by the
programmer:
Declare a data variable Ex: int a;
Steps to be Declare a pointer variable Ex: int *p;
followed while
using pointers Initialize a pointer variable Ex: p = &a;
Access data using pointer variable Ex: printf(”%d”,*p);
C Programming Techniques : 12.3
¨ The variables along with pointer variables have to be declared in the beginning of
a function. These declarations can be in any order.
¨ Only point we have to remember is that before using pointers to access anything,
the pointers have to be initialized with appropriate addresses.

12.2.1 Pointer declaration and Definition


In C language, we know that all the variables should be declared before they are used.
Pointer variables also should be declared before they are used. In this section, let us
see “How to declare pointer variables?” The syntax to declare a pointer variable is
shown below:
type * identifier ;

Name given to the pointer variable


The asterisk (*) in between type and identifier
tells that the identifier is a pointer variable
type can be any data type such as int, float,
char etc. It can be derived/user-defined data
type also.
For example,
¨ If a variable p contains address of int variable, its declaration is: int *p;
¨ If a variable x contains address of float variable, its declaration is: float *x;
¨ If a variable y contains address of char variable, its declaration is: char *y;
¨ If a variable z contains address of double variable, its declaration is: double *z;
¨ If a variable fp contains address of FILE variable, its declaration is: FILE *fp;
Note: In the above declarations we say:
1) p is a pointer to an int
2) x is a pointer to a float
3) y is a pointer to a char
4) z is a pointer to a double
5) fp is a pointer to FILE (details are in FILE HANDLING: CHAPTER 14)

Example 12.2: In the declaration, the position of * is immaterial. For example, all the
following declarations are same:
int *pa;
int * pa;
int* pa;
12.4 : Pointers
Any of the above declaration informs that the variable pa is a pointer variable and it
should contain address of integer variable.
Example 12.3: Consider the multiple declarations as shown below:
int* pa, pb, pc;

Observe the following points:


¨ In the above declaration, most of the readers wrongly assume that the variables pa,
pb and pc are pointer variables. This is because * is attached to int.
¨ This assumption is wrong. Only pa is a pointer variable, whereas the variables pb
and pc are ordinary integer variables.
¨ For better readability, the above declaration can be written as shown below:
int *pa, pb, pc;
Now, we can easily say that pa is pointer variable because of * operator, whereas
pb and pc are integer variables and are not pointer variables.
¨ It is still better if the variables are declared in separate lines as shown below:
int *pa;
int pb;
int pc;

12.2.2 Dangling pointers


In the previous section, we have seen the method of declaring a pointer variable. For
example, consider the following declaration:

int *p;

This indicates that p is a pointer variable and the corresponding memory location
should contain address of an integer variable. But, the declaration will not initialize
the memory location and memory contains garbage value as shown below:

p Garbage value

Here, the pointer variable p does not contain a valid address and we say that it is a
dangling pointer. Now, let us see “What is a dangling pointer?”

Definition: A pointer variable which does not contain a valid address is called
dangling pointer.
C Programming Techniques : 12.5
Example 12.4: Consider following declarations and assume all are local variables.
int *pi; /* Pointer to an integer */
float *pf; /* Pointer to a float number */
char *pc; /* Pointer to a character */

¨ The local variables are not initialized by the compiler during compilation. This is
because, the local variables are created and used only during execution time.
¨ The pointer variables also will not be initialized and hence they normally contain
some garbage values and hence are called dangling pointers.
¨ The memory organization is shown below:
…..
…..

pi Garbage value
pf Garbage value
pc Garbage value
…..
…..
The pointer variables pi, pf and pc does not contain valid addresses and hence they
are dangling pointers.
Note: Most of the errors in programming are due to un-initialized pointers. These
errors are very difficult to debug. So, it is the responsibility of the programmer to
avoid dangling pointers. Hence, it is necessary to initialize the pointer variables so
that they always contain valid addresses.

Example 12.5: Consider following declarations and assume all are global variables.
int *pi; /* Pointer to an integer */
float *pf; /* Pointer to a float number */
char *pc; /* Pointer to a character */

All global variables are initialized by the compiler during compilation. The pointer
variables are initialized to NULL indicating they do not point to any memory
locations as shown below:
pi NULL
pf NULL
pc
NULL
12.6 : Pointers
12.2.4 Initializing a pointer variable
Now, the question is “How to initialize a pointer variable?” Initialization of a pointer
variable is the process of assigning the address of a variable to a pointer variable. The
initialization of a pointer variable can be done using following three steps:
Step 1: Declare a data variable
Step 2: Declare a pointer variable
Step 3: Assign address of a data variable to pointer variable
using & operator and assignment operator
Note that the steps 1 and 2 can be interchanged i.e., we can first declare a pointer
variable, then declare a data variable and then initialize the pointer variable. The three
ways using which initialization can be done is described below:
Method 1: Declaring a data variable, pointer variable and initializing pointer
variable in separate statements. For example, consider the following three statements:
int x; /* Step 1: x is declared as an integer data variable */
int *px; /* Step 2: px is declared as a pointer variable */
px = & x; /* Step 3: copy address of data variable to pointer variable */

Method 2:Declaring a pointer and initializing a pointer in a single statement: Using


this method, the above three statements can be written as shown below:

int x;
int *px = &x;

Method 3: Declaring a data variable, pointer variable and initializing a pointer


variable in a single statement: Using this method, the above two statements can be
written as shown below:

int x, *px = &x;

Example 12.6: Consider the following statements:


int p, *ip;
float d, f;
ip = p; /* ERROR: The ip should contain address of a variable */
ip = &d; /* ERROR: ip is pointer to int. But, it contains address of
double variable */
C Programming Techniques : 12.7
ip = &p; /* OK */

Observe the following points:


¨ Consider the first statement:

ip = p;

Here, ip is a pointer to integer. It should contain the address. But, we are not
storing the address. Hence, it is an error.

¨ Consider the second statement:

ip = &d;
Here, ip should contain address of integer variable. But, we are storing address of
float variable. So, it results in error.

Now, let us write some programs using two pointers

Example 12.7: Write a program to add two numbers using pointers

PROGRAM TRACING
1. #include <stdio.h>
2.
3. void main() Execution starts from main
sum
4.{
5. int a = 10, b = 20, sum; a 10 b 20 30
6
7. int *pa, *pb;
8.
9. pa = &a; pa pb
10. pb = &b;
11.
12. sum = *pa + *pb; sum = 10 + 20 =30
13.
14. Output
15. printf(“Sum = %d\n”, sum); Sum = 30
16.}
12.8 : Pointers
Example 12.8: Program to read two numbers and add two numbers using pointers

PROGRAM TRACING
1. #include <stdio.h>
2.
3. void main() Execution starts from main
4.{ sum
5. int a, b, sum; a 10 b 20 30
6
7. int *pa, *pb;
8.
9. pa = &a; pa pb
10. pb = &b;
11. Input
12. scanf(“%d %d”,&a, &b); 10 20
13. a = 10 b = 20
14. sum = *pa + *pb; sum = 10 + 20 =30
15. Output
16. printf(“Sum = %d\n”, sum); Sum = 30
17.}

Note: After executing statement 12, the values 10 and 20 which are read from the
keyboard are copied into memory locations identified by a and b. Then those values
are accessed using pointer variables pa and pb, added and result is stored in the
variable sum.

Note: In the statement in line 12 i.e., scanf(“%d %d”, &a, &b );


we are using &a and &b. In line 9 and 10, &a and &b are already copied into pointer
variables pa and pb. So, in place of &a and &b, we can use the pointer variables pa
and pb as shown below:
scanf(“%d %d”, pa, pb ); /* Since pa contains &a, pb contains &b */
Note: there is no need of writing &pa and &pb, since pa and pb already contains the
addresses.

12.3 Pointers are flexible


The pointers are very flexible and can be used in variety of situations as shown
below:
¨ A pointer can point to different memory locations
¨ Two or more pointers can point to same memory location
C Programming Techniques : 12.9
¨ Altering functional arguments using pointers (Pointers and function arguments)
¨ Functions returning pointers
¨ Pointers to pointers
¨ Arrays and pointers
¨ Pointer can point to a single dimensional array
¨ Arrays of pointers
¨ Pointer can point to a function
12.3.1 A pointer pointing to different memory locations
A pointer can point to different data variables by storing the address of appropriate
variables. This can be explained using the following program segment:
int x = 10, y = 20, z = 30;
int *p;
Output 10 x
p = &x; 1
1 printf(“%d\n”, *p); //10 p
20 y
p = &y; 2
2 printf(“%d\n”, *p); //20
3 30 z
p = &z;
3 printf(“%d\n”, *p); //30

Observe the following points:


1 ¨ The pointer variable p contains the address of x. So, output is 10
2 ¨ The pointer variable p contains the address of y. So, output is 20
3 ¨ The pointer variable p contains the address of y. So, output is 30
It is observed from above example that the pointer variable p points to different
memory locations by storing the addresses of different variables. But, at any point of
time, p points to only one memory location. Thus, same pointer can be pointed to
different data variables.
12.3.2 Two or more pointers can point to same memory locations
Variables Address
Consider the statements shown below:
p 5000 Garbage value
1
int *p; q 5002 Garbage value

int *q; r 5004 Garbage value

x 5006 10
12.10 : Pointers
int *r;
int x = 10;

2
p = &x; p 5000

q = &x; q 5002

r = &x; r 5004

x 5006 10

3
printf(“&p =%u, p = %u, *p = %d\n”,&p, p, *p); /* Output */
&p = 5000, p = 5006, *p = 10
printf(“&q =%u, q = %u, *q = %d\n”,&q, q, *q); /* Output */
&q = 5002, q = 5006, *q = 10
printf(“&r =%u, r = %u, *r = %d\n”,&r, r, *r); /* Output */
&r = 5004, r = 5006, *r = 10

Observe the following points from the above program segment:


¨ In the first set of instructions, memory is allocated for all pointer variables but
1 the pointers are not initialized. Hence, they contain garbage values and hence
they are called dangling pointers. Only the variable x is initialized.
¨ After executing the second set of statements, the pointer variables p, q and r
2 contains the address of integer variable x and logical representation is shown
in above figure.
¨ After executing the third set of instructions, even though various pointers have
3 different addressed, all of them points to same set of memory locations. So, the
output is 10.
Note: Even though the variables p, q and r have different addresses, they contain
address of x only. So, different pointer variables (p, q and r in this example) contain
address of one variable (x in this example). So, the value of x can be accessed and
changed using the variables p, q, r and x. In general, there can be multiple pointers to
a variable.

12.4.2 Pointers to Pointers

We have used pointers which directly points to data. In this section, let us see “What
is pointer to a pointer?”
C Programming Techniques : 12.11

Definition: A variable which contains address of a pointer variable is called pointer


to a pointer. For example, consider the following declarations:

int a;
int *p1;
int **p2;
¨ The first declaration instructs the compiler to allocate the memory for the variable
a in which integer data can be stored.
¨ The second declaration tells the compiler to allocate a memory for the variable p1
in which address of an integer variable can be stored.
¨ The third declaration tells the compiler to allocate a memory for the variable p2 in
which address of a pointer variable which points to an integer can be stored. The
memory organization for the above three declarations is shown below:
p2 p1 a
Garbage Garbage
value
?
value

Assume the above declarations are followed by the following assignment statements:

a = 10;
p1 = &a;
p2 = &p1;
The memory organization after executing the statement a = 10 is shown below:
p2 p1 a
Garbage Garbage
value 10
value

The memory organization after executing the statement p1 = &a is shown below:
p2 p1 a
Garbage
value
10

The memory organization after executing the statement p2 = &p1 is shown below:
p2 p1 a
10
12.12 : Pointers
The data item 10 can be accessed using three variables a, p1 and p2 are shown below:

a refers to the data item 10.


*p1 refers to the data item 10. Here, using p1 and one indirection
operator, the data item 10 can be accessed.
**p2 refers to the data item 10. Here, using p2 and two indirection
operators the data item 10 can be accessed (i.e., *p2 refers to p1 and
**p2 refers to a)

The following program illustrates the way the data item 10 can be accessed using the
variable a, using a pointer variable p1 and pointer to a pointer variable p2.

Example 12.14: Program to access 10, using a variable, pointer variable and pointer
to a pointer variable
#include <stdio.h> TRACING
void main()
{ p2 p1 a
int a;
Garbage Garbage
int *p1; value ?
value
int **p2;
p2 p1 a
Garbage Garbage
a = 10; value
10
value

p2 p1 a
p1 = &a; Garbage
value 10

p2 p1 a
p2 = &p1;
10

Output
printf(“a = %d\n”,a); a = 10
printf(“*p1 = %d\n”, *p1); *p1 = 10
printf(“**p2 = %d\n”, **p2); **p2 = 10
}
C Programming Techniques : 12.13
Note: If x is declared as integer, which of the following statements is true and which
is false?
a. The expression *&x and x are the same. // it is true
b. The expression *&x and &*x are the same. // it is false

illegal

Example 12.15: Given the following declarations:


int a = 5;
int b = 7;
int *p = &a;
int *q = &b;

What is the value of each of the following expressions?


a. ++a;
b. ++(*p);
c. – – (*q);
d. – –b;

Solution: The tracing of the above program segment is shown below:


/* Memory representation for the declarations */
int a = 5; a 5 b 7
int b = 7;
int *p = &a;
int *q = &b; p q

/* Increment a */
a 6 b 7
++a;

p q

/* Access a using pointer variable p */ a 7 b 7


++(*p);

p q

a 7 b 6
/* Access b using pointer variable q*/
--(*q);
p q
12.14 : Pointers

a 7 b 5
/* Decrement b */
--b;
p q
Output a=7 b=5
*p = 7 *q = 5

12.5 Arrays and pointers


Consider the following declaration:
int a[5] = {10, 20, 30, 40, 50};

Observe the following points:


¨ The compiler treats the array a as a pointer and memory is allocated for variable a.
¨ It then allocates 5 memory locations and address of the first memory location (say
0100) is copied into pointer variable a as shown in the diagram.
¨ The compiler then initializes all five memory locations with values 10, 20, 30, 40
and 50 respectively as shown in figure below:
a 0100
Note: Assuming size of integer
&a[0] 0100 10 a[0] is 2 bytes, two bytes are reserved
&a[1] 0102 20 a[1] for each memory location
&a[2] 0104 30 a[2]
Note: The starting address of the
&a[3] 0106 40 a[3] first byte of the array is called
50 base address which is 0100.
&a[4] 0108 a[4]

Note: The address of the 0th memory location 0100 stored in a cannot be changed. So,
even though a contains an address, since its value cannot be changed, we call a as
pointer constant. Observe that &a[0] and a are same.

a &a[0] (a + 0)
same same
To justify above points, now let us see “What is the output of the following
program?”
C Programming Techniques : 12.15
PROGRAM TRACING
#include <stdio.h>

void main()
{
int a[5] = {10, 20, 30, 40, 50}; Output

printf(“%u %u %u\n”, &a[0], a, a+0); 0100 0100 0100


}

Note: We may get different answer in our computer. But, whatever it is, observe that
the value of &a[0] or a or a+0 are same.

Now, let us see “How to access the address of each element?” The address of each
item can be accessed using two different ways:

address operator base address


with index with index

&a[0] i.e, 1000 (a+0) i.e., 0100


&a[1] i.e., 1002 (a+1) i.e., 0102
&a[2] i.e., 1004 (a+2) i.e., 0104
&a[3] i.e., 1006 (a+3) i.e., 0106
&a[4] i.e., 1008 (a+4) i.e., 0108

In general,
&a[i] (a +i) where i = 0 to 4
is same as 0 to 5-1
0 to n – 1 (in general)
Note: The various ways of accessing the address of ith item in an array a is shown
below:

&a[i] is same as a + i
same same
&i[a] is same as i + a

So, address of a[i] can be obtained using any of the following notations:

&a[i] or a+i or i+a or &i[a]


12.16 : Pointers

The data in those addresses can be obtained using the indirection operator * as shown
below:

*&a[i] or *(a+i) or *(i+a) or *&i[a]


Note: The pair *& get cancelled each other

a[i] i[a]
So, *(a+i) or *(i+a) or a[i] or i[a] or a[i] or i[a] are one and the same.

To justify this answer, consider the following program:

#include <stdio.h> a = 0100

&a[0] 0100 10 a[0]


void main()
{ &a[1] 0102 20 a[1]
int a[5] = {10, 20, 30, 40, 50}; &a[2] 0104 30 a[2]
int i = 3; 40 a[3]
&a[3] 0106
&a[4] 0108 50 a[4]

printf(“%d %d %d %d %d %d \n”, *(&a[i]), a[i], *(a+i), *(i+a), i[a], *&i[a]);


}
Output 40 40 40 40 40 40

Note: It is observed from the above example that: a[i] is same as *(a+i) denoted
using pointer concept. So, any array program can be written using pointers.

12.5.1 Largest of N numbers

Consider 5 elements 10, 20, 50, 25 and 15. It is required to find the largest of these 5
numbers. Now, let us see “How to write the program to find largest of N numbers?”

Design: Assume the variable big contains 10 which is the 0th element of the array and
pos is 0 which is the position of that element. The equivalent code can be written as:

big = a[0]; /* Assume first item is big */


Initialization
pos = 0; /* Store 0 as the position of 0th item */
C Programming Techniques : 12.17
Since 0th item 10 is in big, the rest of the items such as a[1], a[2], a[3] and a[4]
should be compared with big as shown in figure:

a[0] a[1] a[2] a[3] a[4]


if ( a[i] > big ) 10 20 50 25 15
{ a
big = a[i];
pos = i;
big = 10
} i = 1 to 4.
i = 1 to 5-1 where 5 indicates the number of elements
In general, i = 1 to n-1 where n = 5 indicates the number of elements.

So, the code can be written as shown below:

for ( i = 1; i <= n-1; i++)


{
if ( a[i] > big )
{
big = a[i]; Main logic
pos = i;
}
}

Note: When we know the program using arrays, we can easily write the program
using pointers. We have seen that a[i] is same as *(a+i) or *(i+a) or i[a]. So, replace
a[i] by *(a+i) to get the program using pointers.

Now, the complete program to find the largest of N elements using an array and
using pointer with indexing is shown below:
12.18 : Pointers
Example 12.16: Program to compute largest and its position

Using Arrays Using Pointer with indexing


#include <stdio.h> #include <stdio.h>
void main() void main()
{ {
int a[10], n, i, big, pos; int a[10], n, i, big, pos;
printf("Enter number of elements\n"); printf("Enter number of elements\n");
scanf("%d",&n); scanf("%d",&n);
printf(“Enter the elements\n”); printf(“Enter the elements\n”);
for ( i = 0; i <= n-1; i++) for ( i = 0; i <= n-1; i++)
scanf("%d",&a[i]); scanf("%d",a+i); /* (a+i) = &a[i] */
big = a[0]; big = *(a+0);
pos = 0; pos = 0;
for ( i = 1; i <= n-1; i++) for ( i = 1; i <= n-1; i++)
{ {
if ( a[i] > big ) if ( *(a+i) > big )
{ {
big = a[i]; big = *(a+i);
pos = i; pos = i;
} }
} }
printf("Largest = %d\n”,big); printf("Largest = %d\n”,big);
printf(“Position = %d\n", pos+1); printf(“Position = %d\n", pos+1);
} }

12.5.2 Pointers and other operators

Like normal variables in an expression, pointer variables in expressions can also be


used. If p1 and p2 are pointer variables that are declared and initialized properly, *p1
and *p2 represent the values to be manipulated. So, operations such as relational,
arithmetic, logical etc., can be performed on *p1 and *p2.

Example 12.17: Valid statements with operations such as multiplication and addition

¨ x = *p1 * *p2; // The values pointed by p1 and p2 are multiplied


¨ sum = sum + *p1; // The value pointed to by p1 is added to sum
¨ *p1 = *p1 + 1; // value pointed to by p1 is incremented by 1
C Programming Techniques : 12.19

¨ x = *p1 /*p2; // Error: This expression is wrong because /* before p2


// is treated as beginning of the comment in C

Note: The error in the above statement can be eliminated by inserting the space
between / and * as shown below:

¨ x = *p1 / *p2 // Correct: Since there exists space between / and *, it is


// treated as division operation not as beginning of the
// comment

Note: Even though various operations can be performed on *p1 and *p2 (since they
represent the values to be manipulated), the operations are restricted on p1 and p2
since they contain only the addresses. The various operations that can be performed
on pointer variables are shown below:

Adding an integer to a pointer


Operations Subtracting an integer from pointer
performed
on pointers Subtracting two pointers
Comparing two pointers

12.5.3 Adding an integer to a pointer


An integer can be added to a pointer. This can be explained using the following
example.

Example 12.18: Consider the following declaration:


int a[5] = {10, 20, 30, 40, 50};
int *p1, *p2;
p1 = a;
p2 = a;

The various valid and invalid statements are shown below:


¨ p1 = p1 + 1; /* Valid: Points to next element */
¨ p1 = p1 + 3; /* Valid: Points to 3rd element from p1*/
¨ p1 + p2; /* Invalid: Two pointers cannot be added */
¨ p1++; /* Valid: Same as p1 = p1 + 1 */
12.20 : Pointers
Example 12.19: Pointer arithmetic using increment operator

int a[5]={10, 20, 30, 40, 50}; float a[5]={10.555, 20, 30, 40, 50};
int *p; float *p;
p = a; /* p points to a */ p = a; /* p points to a */

Assuming base address of a is Assuming base address of a is 0100,


0100, the variable p points to the variable p points to first item as
first item as shown below: shown below:
a a
p 0100 10 p 0100 10.555
0102 20 0104 20.0
0104 30 0108 30.0
0106 40 0112 40.0
0108 50 0116 50.0

After executing the statement: After executing the statement:


p++; p++;
the pointer variable p points to the the pointer variable p points to the next
next integer. floating point number.

Note: Each time p++ is executed, Note: Each time p++ is executed, its
its value will be incremented by 2 value will be incremented by 4 because
because size of integer is 2 bytes. size of floating point number is 4 bytes.
In other words, p points to the In other words, p points to the next
next item. item.

Note: In general, if p is a pointer variable pointing to an array, after executing the


statement:
p++;

the pointer variable is incremented by:


¨ 1 for character array
¨ 2 for integer array
¨ 4 for floating point array and 8 for double and so on. In other words, the
pointer points to the next item of an array.

12.5.4 Display array elements using pointers

Now, let us see “How to write a program to display array elements using pointer?”
C Programming Techniques : 12.21

Design: Consider the following array and assume p points to the beginning of the
array. To start with p points to 0100 and *p refers to 10. Let us observe the outputs in
various iterations shown below:
0100 0102 0104 0106 0108 0110
beginning
10 20 30 40 50
of array
p p p p p p
Iterations: i = 0 1 2 3 4

print 10 and increment p using


printf(“%d\n”, *p); // 10
p++; // 0102
print 20 and increment p using
printf(“%d\n”, *p); // 20
p++; // 0104
print 30 and increment p using
printf(“%d\n”, *p); // 30
p++; // 0106
print 40 and increment p using
printf(“%d\n”, *p); // 40
p++; // 0108
print 50 and increment p using
printf(“%d\n”, *p); q // 50
p++; // 0110

In general, observe that the following two statements:

printf(“%d\n”, *p);
p++;

are repeatedly executed for i = 0 to 4, to get the output 10, 20, 30, 40 and 50. The C
equivalent statement using for loop is shown below:
for (i = 0; i <= 4; i++) /* i <= 4 is same as i < 5 */
{
printf(“%d\n”, *p);
p++;
}
12.22 : Pointers
The complete program is shown below:

Example 12.20: Program to display array elements using pointer

#include <stdio.h>
void main()
{
int a[] = {10, 20, 30, 40, 50 };
int *p;
int i;

p = a; /* same as p = &a[0] */

for ( i = 0; i <= 4; i++)


{
printf("%d ",*p); 10 20 30 40 50
p++;
}
printf("\n");
}
12.5.5 Sum of N numbers using pointers
In the previous example, instead of printf() within the for loop, if we use the
statement
sum = sum + *p;
then we add all the elements of the array. The complete program to add n elements is
shown below:

Example 12.21: Program to compute sum of elements of array

#include <stdio.h>

void main()
{
int a[] = {10, 20, 30, 40, 50 };
int *p;
int i, sum;

p = a; /* point p to the first element */


C Programming Techniques : 12.23
sum = 0; /* Initialize sum to 0 */

for ( i = 0; i <= 4; i++)


{
sum = sum + *p; /* Same as */
p++; sum = sum + *p++; or sum = sum + *(p++);
}

printf("Sum of all the numbers = %d\n",sum);


}

Note: Observe that by executing p++, we can point p to the next element. On similar
lines by executing p--, we can point p to the previous element in an array.

12.5.6 Subtracting an integer from a pointer

Subtraction can be performed when first operand is a pointer and the second operand
is an integer. This can be explained by considering the following example.

Example 12.22: Consider the following declaration and initialization:


int a[5] = {10, 20, 30, 40, 50};
int *p1;
p1 = &a[4];

The various valid and invalid statements are shown below:


¨ p1 = p1 – 1; /* Valid */
¨ p1 = p1 – 3; /* Valid */
¨ p1--; /* Valid: Same as p1 = p1 – 1 */
¨ --p1; /* Valid: Same as p1 = p1 – 1 */
¨ p1 = 1 – p1; /* Invalid: The first operand should be a pointer

Example 12.23: Write a program to display array elements using pointer from last
element to first element.

Note: As we execute p++, pointer variable p points to next element, if we execute p--,
pointer variable p points to the previous element.

Design: To get the array elements in reverse order, point the variable p to point to the
end of the array and replace p++ by p– – in the previous program. The complete
program is shown below:

#include <stdio.h>
12.24 : Pointers
void main()
{
int a[] = {10, 20, 30, 40, 50 };
int *p;
int i;

p = &a[4]; /* point p to the last element*/


a
for ( i = 0; i <= 4; i++) Output
{ 0100 10
printf("%d ",*p); p 0102 20 50 40 30 20 10
p--; 0104 30
} 0106 40
printf("\n"); 0108 50
}
p points to previous element after executing p--
and items are accessed from bottom to top.
12.5.7 Subtracting two pointers
If two pointers are associated with the same array, then subtraction of two pointers is
allowed. But, if the two pointers are associated with different arrays, even though
subtraction of two pointers is allowed, the result is meaningless.

Consider the following declaration and initialization:


int a[5] = {10, 20, 30, 40, 50};
int *p1;
int *p2;
float *f;
p1 = a; /* same as p1 = &a[0] */
p2 = &a[4];

The various valid and invalid statements are shown below:


¨ p2 – p1; /* Valid */
¨ p1 – p2; /* Valid */
¨ f – p1; /* Invalid: Since type of both operands is not same */

The memory map for the above declaration is shown below:


p1 4 elements away p2

0100 0102 0104 0106 0108


10 20 30 40 50
C Programming Techniques : 12.25
Note: Observe following facts from above figure:
¨ p2 has an address 0108 and p1 has address 0100.
¨ But, p2 – p1 is not 0108-0100. Actually, it is (0108-0100)/sizeof(int) i.e.,
(0108-0100)/2 = 4
¨ So, p2 – p1 gives us 4 which indicates that p2 is at a distance of 4 elements
away from p1.
¨ So, p2 – p1 +1 gives the number of elements in the array

12.5.8 Comparing two pointers

If two pointers are associated with the same array, then comparison of two pointers is
allowed using relational operators. But, if the two pointers are associated with
different arrays, even though comparisons of two pointers is allowed, the result is
meaningless.

Consider the following declaration and initialization:


int a[5] = {10, 20, 30, 40, 50};
int *p1;
int *p2;
float *f;
p1 = a; /* or p1 = &a[0] */
p2 = &a[4];
The various valid and invalid statements are shown below:
¨ p2 != p1; /* Valid */;
¨ p1 == p2; /* Valid */;
¨ p1 <= p2; /* Valid */;
¨ p1 >= p2; /* Valid */
¨ f != p1; /* Invalid: Since type of both operands is not same */
Note: Multiplying and dividing a pointer variable with any other variable or integer is
not allowed.

Now, let us see “How to write a program to display array elements by comparing
of two pointers?”
Design: Let us use two pointers p and q where p points to the first element of array a
and q points to the last element of array a as shown below:
p q

0100 0102 0104 0106 0108


a 10 20 30 40 50
12.26 : Pointers

Observe from the above figure that as long as p <= q, value pointed to by p can be
printed and updated using the following statements:
while (p <= q)
{ Output
printf("%d ",*p); 10 20 30 40 50
p++;
}
So, the complete program is shown below:
Example 12.24: Program to display array elements by comparing pointers
#include <stdio.h>
void main()
{
int a[] = {10, 20, 30, 40, 50 };
int *p;
int *q;
p = &a[0]; /* point p to the first element */
q = &a[4]; /* point q to the last element*/
while (p <= q) /* Comparing two pointer values */
{
printf("%d ",*p); 10 20 30 40 50
p++;
}
printf("\n");
}

Note: Two pointer subtractions and two pointer comparisons are generally performed
if both the pointers point to the same array.

12.6 Passing an array to a function / character pointer and functions

As we pass various parameters to functions, we can also pass name of an array as a


parameter. Note: Name of an array is a pointer to the first element. So, when we pass
an array to a function we should not use the address operator. The syntax of a
function call is:
function_name (a); /* Here a should have been declared as array */

The two ways of declaring and using the array in the called function are:
C Programming Techniques : 12.27
¨ using pointer declaration
¨ using array declaration

void function_name(int a[]) void function_name(int *a)


{ {
/* ith item can be accessed /* ith item can be accessed
using a[i] using *(a+i)
*/ */
} }

Note: Easier way of writing a program using pointers


¨ write a program using arrays i.e., may be using a[i] or a[j] etc.
¨ Then replacing a[i] by *(a+i) and a[j] by *(a+j) we get the program using
pointers.

Now, using the above technique, any array program can be converted into a program
using pointers.

12.6.1 strlen(str) – String Length

Consider the function to find the length of the string (Refer example 10.11, section
10.5.1 for design details). Various versions of the functions are written side by side to
show the difference:

Example 12.25: Function returning the string length


Using arrays Using pointers
int my_strlen(char str[]) int my_strlen(char *str) int my_strlen(char *str)
{ { {
int i = 0; int i = 0; char *ptr = str;

/* compute the length */ /* compute length */ while (*ptr++)


while (str[i] != ‘\0’) while (*(str +i) ) ;
i++; i++;
return ptr-str;
return i; return i; }
} }

The C program to access any of the above functions can be written as shown below:
12.28 : Pointers
Example 12.26: Program using the user-defined function my_strlen()

#include <stdio.h>
/* Include: Example 12.25: to compute the length */

void main()
{
char str[20];
int i; Input

printf("Enter the string\n"); Enter the string


gets(str); Rama
i = my_strlen(str) ; i=4
Output
printf("Length = %d\n", i); Length = 4
}

12.6.2 strcpy(dest, src) – string copy


Now, let us write a function to implement strcpy (Refer section 10.5.2, example 10.14
for design details). So, the final function to copy the contents of source string src to
destination string dest using arrays as well as using pointers is shown below:

Example 12.27: Function to copy string src to string dest using 3 methods.
Using arrays Using Pointers
void my_strcpy(char *dest, char *src)
void my_strcpy(char dest[], char src[])
{ {
int i = 0; /* copy the string */
while ( *src != ‘\0’)
/* Copy the string */ *dest++ = *src++;
while (src[i] != ‘\0’) /* attach null character at end */
{ *dest = ‘\0’;
dest[i] = src[i]; }
i++;
} Note: Following is most efficient one
void my_strcpy(char *dest, char *src)
/* Attach null character at the end */ {
dest[i] = ‘\0’; while (*dest++ = *src++)
} ;
}
C Programming Techniques : 12.29
Note: Observe the null statement “;” in the third version of my_strcpy. It does nothing.
The condition in the while loop i.e., *dest++ = *src++ is repeatedly executed and
each character of the source is copied into destination including ‘\0’. Once ‘\0’ is
reached, the condition fails and control comes out of the loop. The complete program
which uses the user defined function is shown below:

Example 12.28: Program using the user-defined function my_strcpy()


#include <stdio.h>
/* Include: Example 12.27 to compute the length */
void main()
{
char src[20], dest[20]; TRACING
printf("Enter the string\n"); Enter the string
gets(src); RAMA
my_strcpy(dest, src); dest = “RAMA”
printf("Dest string = %s\n", dest); Dest string = RAMA
}

12.6.3 strcmp(s1, s2) – string compare


This function is used to compare two strings. The design details are given in section
10.5.7, example 10.25. The function using arrays and pointers are given side by side
below:

Example 12.29: Function to compute two strings.


Using arrays Using Pointers
int my_strcmp(char s1[], char s2[]) int my_stcmp(char *s1, char *s2)
{ {
int i;
i = 0; while (*s1 == *s2)
while (s1[i] == s2[i]) {
{ if (*s1 == ‘\0’) break;
if (s1[i] == ‘\0’) break;
i++ s1++, s2++;
} }

return s1[i] – s2[i]; return *s1 - *s2;


} }
12.30 : Pointers
The above function returns one of the following values:
¨ zero if s1 = s2
¨ positive if s1 > s2
¨ negative if s1 < s2

The complete program showing the usage of my_strcmp is shown below:

Example 12.30: C program showing the usage of my_strcmp


#include <stdio.h>
/* Include: example 12.29: Function my_strcmp */
void main()
{
char s1[] = "RAMA";
char s2[] = "KRISHNA";
int difference;
difference = my_strcmp(s1, s2);
if (difference == 0)
printf("String s1 = string s2\n");
else if (difference >0)
printf("String s1 > string s2\n");
else
printf("String s1 < string s2\n");
}

12.7 Understanding complex declarations


Note that it is very difficult to interpret and understand the declarations especially
related to pointers. To read and understand the complicated declarations, we can
follow the right-left rule. Now, let us see “What is right-left rule?”
Definition: The right-left rule can be stated as follows:
¨ Start with the identifier in the center
of declaration
end
¨ Read the declarations in a spiral
manner once going right and then identifier
left, again right and left and so on till
all entities are read i.e, right-left
reading of each symbol is done start
alternatively spinally. This concept
can be represented pictorially as
shown on the right hand side.
C Programming Techniques : 12.31
Example 12.31: Interpret the declaration: int x. The declaration can be pictorially
represented as shwon below:

end is an Note: Read and interpret the entity in each box


int x in the direction of the arrow mark along with
labels.

start i.e., x is an int. In other words, x is an integer

Example 12.32: Interpret the declaration: int *p. The declaration can be pictorially
represented as shwon below:
to
Reading in the direction of
end is a arrow along with the labels we
have:
int * p
p is a * to int
i.e., p is a pointer to an integer
start [By reading * as pointer, int as
integer]

Example 12.33: Interpret the declaration: int a[10]. The declaration can be
pictorially represented as shwon below:
is an array of
Reading in the direction of arrow
end
along with the labels we have:
int a [10]
a is an array of 10 int
i.e., a is an array of 10 integer
start
[By reading int as integer]
Example 12.34: Interpret the declaration: int *p[5]. The declaration can be
pictorially represented as shwon below:
to
is an array of Reading in the direction of
end
arrow along with the labels we
int * p [5] have:
p is an array of 5 * to int
i.e., p is an array of 5 pointers
start to integers where * is pointer,
int is integer
Example 12.35: Interpret the declaration: int (*p) [5]. The declaration can be
pictorially represented as shwon below:
12.32 : Pointers

to an array of Note: Preference is given for the


end is a expression withing parantheses.
Reading in the direction of arrow
int * p [5] along with the labels we have:
p is a * to an array of [5] int i.e.,
start p is a pointer to an array of 5
integers where * is pointer, int is
integer
Example 12.36: Interpret the declaration: int a (int b). The declaration can be
pictorially represented as shwon below:

is a function
end
int a (int b) with b as integer parameter

start
returning
Note: If an identifier is followed by (….), it indicates a function call or function
declaration. So, reading in the direction of arrow along with the labels we have:
a is a function with (int b) and returning int
i.e., a is a function which accepts b an integer as a parameter and returning an integer

12.8 Memory allocation functions


C Programming Techniques : 12.33
Now, let us see “What is static memory allocation?”

Note: If there is an unpredictable storage requirement, then static allocation technique


is not at all used. This is the point where the concept of dynamic allocation comes
into picture. Now, the question is “What is dynamic memory allocation?”
12.34 : Pointers

Now, let us see “What are the differences between static memory allocation and
dynamic memory allocation?” The various differences between static allocation and
dynamic allocation technique are shown below:

Static allocation technique Dynamic allocation technique


1. Memory is allocated during 1. Memory is allocated during
compilation time execution time

2. The size of the memory to be 2. When required memory can be


allocated is fixed during allocated and when not required
compilation time and cannot be memory can be de-allocated
altered during execution time
3. Used only when the data size is 3. Used only for unpredictable
fixed and known in advance before memory requirement.
processing

4. Execution is faster, since memory is 4. Execution is slower since memory


already allocated and data has to be allocated during run time.
manipulation is done on these Data manipulation is done only
allocated memory locations after allocating the memory.
5. Memory is allocated either in stack 5. Memory is allocated only in heap
area (for local variables) or data area
area (for global and static
variables).
C Programming Techniques : 12.35
6. Ex: arrays 6. Ex: Dynamic arrays, linked lists,
trees

Now, let us see “What are the various memory management functions in C?” Th
12.36 : Pointers

12.8.1 malloc(size)

Now, let us see “What is the purpose of using malloc?” This function allows the
program to allocate memory explicitly as and when required and the exact amount
needed during execution. This function allocates a block of memory. The size of the
block is the number of bytes specified in the parameter. The syntax is shown below:
#include <stdlib.h> /* Prototype definition of malloc() is available */
……..
ptr = (data_type *) malloc(size);
…….
where
¨ ptr is a pointer variable of type data_type
C Programming Techniques : 12.37
¨ data_type can be any of the basic data type or user defined data type
¨ size is the number of bytes required

Observe the following points:


¨ On successful allocation, the function returns the address of first byte of allocated
memory. Since address is returned, the return type is a void pointer. By type
casting appropriately we can use it to store integer, float etc.
¨ If specified size of memory is not available, the condition is called “overflow of
memory”. In such case, the function returns NULL. It is the responsibility of the
programmer to check whether the sufficient memory is allocated or not as shown
below:
void function_name()
{
……..
ptr = (data_type *) malloc(size);
if (ptr == NULL)
{
printf(“Insufficient memory\n”);
exit(0);
}
……..
……..
}

Example 12.37: Program showing the usage of malloc() function


#include <stdio.h> TRACING
#include <stdlib.h>
void main() Execution starts from here
{
int i,n;
int *ptr; Inputs
printf("Enter the number of elements\n"); Enter the number of elements
scanf("%d",&n); 5
ptr = (int *) malloc (sizeof(int)* n);
/* If sufficient memory is not allocated */
if (ptr == NULL)
{
printf("Insuffient memory\n");
return;
12.38 : Pointers
}
/* Read N elements */
printf("Enter N elements\n"); Enter N elements
for (i = 0; i < n; i++)
scanf("%d", ptr+i); 10 20 30 40 50
printf("The given elements are\n");
for (i = 0; i < n; i++) The given elements are
printf("%d ", *(ptr+i)); 10 20 30 40 50
}
12.8.2 calloc(n, size)

Now, let us see “What is the purpose of using calloc?” This function is used to
allocate multiple blocks of memory. Here, calloc – stands for contiguous allocation of
multiple blocks and is mainly used to allocate memory for arrays. The number of
blocks is determined by the first parameter n. The size of each block is equal to the
number of bytes specified in the parameter i.e., size. Thus, total number of bytes
allocated is n*size and all bytes will be initialized to 0. The syntax is shown below:

#include <stdlib.h> /* Prototype definition of calloc() is available */


……..
ptr = (data_type *) calloc(n, size);
……..
where
¨ ptr is a pointer variable of type data_type
¨ data_type can be any of the basic data type or user defined data type
¨ n is the number of blocks to be allocated
¨ size is the number of bytes in each block
Observe the following points:
¨ On successful allocation, the function returns the address of first byte of allocated
memory. Since address is returned, the return type is a void pointer. By type
casting appropriately we can use it to store integer, float etc.
¨ If specified size of memory is not available, the condition is called “overflow of
memory”. In such case, the function returns NULL. It is the responsibility of the
programmer to check whether the sufficient memory is allocated or not as shown
below:

void function_name()
{
……..
ptr = (data_type *) calloc(size);
C Programming Techniques : 12.39

if (ptr == NULL)
{
printf(“Insufficient memory\n”);
exit(0);
}
……..
}

Example 12.38: Program to find maximum of n numbers using dynamic arrays

#include <stdio.h>
#include <stdlib.h>

void main()
{
int *a, i, j, n;
printf("Enter the no. of elements\n");
scanf("%d",&n);

/* Allocate the required number of memory locations dynamically */


a = (int *) calloc( n, sizeof(int) );

if (a == NULL) /* If required amount of memory */


{ /* is not allocated */
printf(“Insufficient memory\n”);
return;
}

printf("Enter %d elements\n", n); /* Read all elements */


for ( i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}

j = 0; /* Initial position of the largest number */


for ( i = 1; i < n; i++)
{
if ( a[i] > a[j] ) j = i; /* obtain position of the largest element*/
}

printf("The biggest = %d is found in pos = %d\n",a[j], j+1);


12.40 : Pointers
free(a); /* free the memory allocated to n numbers */
}

Observe the following points:


¨ The variable a is a pointer to an int.
¨ Once memory is allocated dynamically using calloc(), the address of the first byte
is copied into a.
¨ From this point onwards the variable a can be used as an array or used as a
pointer. If a is used as an array, the ith element can be accessed by a[i] and the
address of ith element can be obtained using &a[i]
¨ If ptr is used as a pointer, the ith element can be accessed by *(a + i) and the
address of ith element can be obtained using (a + i)
¨ In the above program in place of (a + i) we can use &a[i]. At the same time, in
place of *(a + i) we can use a[i]

12.8.3 realloc(ptr, size)

Now, let us see “What is the purpose of using realloc?”

Before using this function, the memory should have been allocated using malloc() or
calloc(). Sometimes, the allocated memory may not be sufficient and we may require
additional memory space. Sometimes, the allocated memory may be much larger and
we want to reduce the size of allocated memory. In both situations, the size of
allocated memory can be changed using realloc() and the process is called
reallocation of memory. The reallocation is done as shown below:
¨ realloc() changes the size of the block by extending or deleting the memory at the
end of the block.
¨ If the existing memory can be extended, ptr value will not be changed
¨ If the memory cannot be extended, this function allocates a completely new block
and copies the contents of existing memory block into new memory block and
then deletes the old memory block. The syntax is shown below:

#include <stdlib.h> /* Prototype definition of realloc() is available */


……..
……..
ptr = (data_type *) realloc(ptr, size);
…….
…….
where
¨ ptr is a pointer to a block of previously allocated memory either using
malloc() or calloc().
C Programming Techniques : 12.41
¨ size is new size of the block
if (ptr == NULL)
{ /* Memory is not allocated */
printf(“Insufficient memory\n”);
return;
}

Now, let us see “What does this function return?” This function returns the following
values:
¨ On successful allocation, the function returns the address of first byte of allocated
memory.
¨ If specified size of memory cannot be allocated, the condition is called “overflow
of memory”. In such case, the function returns NULL.

Example: 12.39: C program showing the usage of realloc() function.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
char *str;
str = (char *) malloc(10); /* allocate memory for the string */
strcpy(str, “Computer”);
str = (char *) realloc(str, 40);
strcpy(str, “Computer Science and Engineering”);
}
12.8.4 free(ptr)
Now, let us see “What is the purpose of using free()?”
This function is used to de-allocate (or free) the allocated block of memory which is
allocated by using the functions calloc(), malloc() or realloc(). It is the responsibility
of a programmer to de-allocate memory whenever it is not required by the program
and initialize ptr to NULL. The syntax is shown below:
#include <stdlib.h> /* Prototype definition of free() is available */
……..
free(ptr);
ptr = NULL;
…….
12.42 : Pointers

Example: 12.40: Sample program to show the problems that occur when free() is not
used.

1. #include <stdlib.h>
2.
3. void main()
4. { a
5. int *a;
6.
7. a = (int *) malloc(sizeof(int)); a
8. *a = 100; 100
9.
10. a = (int *) malloc(sizeof(int)); 200
11. *a = 200;
12. }
Now, let us see “What will happen if the above program is executed?” The various
activities done during execution are shown below:
¨ When control enters into the function main, memory for the variable a will be
allocated and will not be initialized.
¨ When memory is allocated successfully by malloc (line 7), the address of the first
byte is stored in the pointer a and integer 100 is stored in the allocated memory
(line 8).
¨ But, when the memory is allocated successfully by using the function malloc in
line 10, address of the first byte of new memory block is copied into a (shown
using dotted lines.)
Observe that the pointer a points to the most recently allocated memory, thereby
making the earlier allocated memory inaccessible. So, memory location where the
value 100 is stored is inaccessible to any of the program and is not possible to free so
that it can be reused. This problem where in memory is reserved dynamically but not
accessible to any of the program is called memory leakage. So, care should be taken
while allocating and de-allocating the memory. It is the responsibility of the
programmer to allocate the memory and de-allocate the memory when no longer
required.

Note: Observe the following points:


¨ It is an error to free memory with a NULL pointer
¨ It is an error to free a memory pointing to other than the first element of an
allocated block
¨ It is an error to refer to memory after it has been de-allocated
C Programming Techniques : 12.43
Note: Be careful, if we dynamically allocate memory in a function. We know that
local variables vanish when the function is terminated. If ptr is a pointer variable
used in a function, then the memory allocated for ptr is de-allocated automatically.
But, the space allocated dynamically using malloc, calloc or realloc will not be de-
allocated automatically when the control comes out of the function. But, the allocated
memory cannot be accessed and hence cannot be used. This unused un-accessible
memory results in memory leakage.

12.12 Advantages and disadvantages of pointers


By this time, we should have understood the full concepts of C pointers and given any
problem we should be in a position to solve. After understanding the full concepts of
pointers, we should be in a position to answer the question “What are the advantages
and disadvantages of pointers?”
Advantages
¨ More than one value can be returned using pointer concept (pass by reference).
¨ Very compact code can be written using pointers.
¨ Data accessing is much faster when compared to arrays.
¨ Using pointers, we can access byte or word locations and the CPU registers
directly. The pointers in C are mainly useful in processing of non-primitive data
structures such as arrays, linked lists etc.
Disadvantages
¨ Un-initialized pointers or pointers containing invalid addresses can cause system
crash.
¨ It is very easy to use pointers incorrectly, causing bugs that are very difficult to
identify and correct.
¨ They are confusing and difficult to understand in the beginning and if they are
misused the result is not predictable.

You might also like