0% found this document useful (0 votes)
14 views22 pages

Pointers: Objectives

This document provides an overview of pointers in C programming, explaining their definition, usage, and various operations including pointer arithmetic and comparisons. It details how to declare pointer variables, assign values to them, and their relationship with single-dimensional arrays. The document also includes examples to illustrate the concepts discussed.

Uploaded by

bnhatm216
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)
14 views22 pages

Pointers: Objectives

This document provides an overview of pointers in C programming, explaining their definition, usage, and various operations including pointer arithmetic and comparisons. It details how to declare pointer variables, assign values to them, and their relationship with single-dimensional arrays. The document also includes examples to illustrate the concepts discussed.

Uploaded by

bnhatm216
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/ 22

13

Session

Pointers

Concepts
Objectives

At the end of this session, you will be able to:

 Explain what a pointer is and where it is used

 Explain how to use pointer variables and pointer operators

 Assign values to pointers

 Explain pointer arithmetic

 Explain pointer comparisons

 Explain how pointers can be passed as arguments to functions

 Explain pointers and single dimensional arrays

 Explain Pointer and multidimensional arrays

 Explain how allocation of memory takes place

Introduction

A pointer provides a way of accessing a variable without referring to the variable directly. It provides a
symbolic way of using addresses. This session deals with the concept of pointer and its usage in C. Also,
we shall discuss a few concepts which are associated with pointers.

13.1 What is a Pointer?

A Pointer is a variable, which contains the address of a memory location of another variable, rather
than the stored value of that variable. If one variable contains the address of another variable, the first
variable is said to point to the second. A pointer provides an indirect way of accessing the value of a
data item. Consider two variables var1 and var2 such that var1 has a value of 500 and is stored in
the memory location 1000. If var2 is declared as a pointer to the variable var1, the representation will
be as follows:

Elementary Programming with C Version 1.1 © Aptech Limited page 203 of 356
Session 13
Pointers

Memory location Value stored Variable name


Concepts

1000 500 var1


1001
1002
.
.
1108 1000 var2

Here, var2 contains the value 1000, which is nothing but the address of the variable var1.

Pointers can point to variables of other fundamental data type variables like int, char, or double or
data aggregates like arrays.

13.1.1 Why are Pointers used?

Few of the situations where pointers can be used are:

 To return more than one value from a function

 To pass arrays and strings more conveniently from one function to another

 To manipulate arrays easily by moving pointers to them (or to parts of them), instead of moving the
arrays themselves

 To allocate memory and access it (dynamic memory allocation)

13.2 Pointer Variables

If a variable is to be used as a pointer, it must be declared. A pointer declaration consists of a base type,
an *, and a variable name. The general syntax for declaring a pointer variable is:

type *name;

where type is any valid data type, and name is the name of the pointer variable. The declaration tells the
compiler that name is used to store the address of a value corresponding to the data type type. In the
declaration statement, * indicates that a pointer variable is being declared.

In the above example of var1 and var2, since var2 is a pointer, which holds the value of an int type
variable var1, it will be declared as:

int *var2;

page 204 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

Now, var2 can be used in a program to indirectly access the value of var1. Remember, var2 is not of
type int but is a pointer to a variable of type int.

Concepts
The base type of the pointer defines what type of variables the pointer can point to. Technically, any type
of pointer can point anywhere in the memory. However, all pointer arithmetic is done relative to its base
type, so it is important to declare the pointer correctly.

13.3 The Pointer Operators

There are two special operators which are used with pointers: * and &. The & operator is a unary operator
and it returns the memory address of the operand. For example,

var2 = &var1;

places the memory address of var1 into var2. This address is the computer’s internal location of the
variable var1 and has nothing to do with the value of var1. The & operator can be thought of as returning
“the address of”. Therefore, the above assignment means “var2 receives the address of var1”. Referring
back, the value of var1 is 500 and it uses the memory location 1000 to store this value. After the above
assignment, var2 will have the value 1000.

The second pointer operator, *, is the complement of &. It is a unary operator and returns the value
contained in the memory location pointed to by the pointer variable’s value.

Consider the previous example, where var1 has the value 500 and is stored in the memory location
1000, after the statement

var2 = &var1;

var1 contains the value 1000, and after the assignment

temp = *var2;

temp will contain 500 and not 1000. The * operator can be thought of as “at the address”.

Both * and & have a higher precedence than all other arithmetic operators except the unary minus. They
share the same precedence as the unary minus.

The following program prints the value of an integer variable, its address, which is stored in a pointer
variable, and also the address of the pointer variable.

Elementary Programming with C Version 1.1 © Aptech Limited page 205 of 356
Session 13
Pointers

Example 1:
Concepts

#include <stdio.h>
void main()
{
int var = 500, *ptr_var;
/* var is declared as an integer and ptr_var as a pointer pointing to an
integer */
ptr_var = &var; /*stores address of var in ptr_var*/
/*Prints value of variable (var) and address where var is stored */
printf(“The value %d is stored at address %u:”,var,&var);
/*Prints value stored in ptr variable (ptr_var) and address where ptr_var
is stored */
printf(“\nThe value %u is stored at address: %u”, ptr_var, &ptr_var);
/* Prints value of variable (var) and address where var is stored, using
pointer to variable */
printf(“\nThe value %d is stored at address:%u”, *ptr_var, ptr_var);
}

A sample output for the above will be:

The value 500 is stored at address: 65500


The value 65500 is stored at address: 65502
The value 500 is stored at address: 65500

In the above, ptr_var contains the address 65500, which is a memory location where the value of var
is stored. The contents of this memory location (65500) can be obtained by using *, as *ptr_var. Now
*ptr_var represents the value 500, which is the value of var. Since ptr_var is also a variable, its
address can be printed by prefixing it with &. In the above case, ptr_var is stored at location 65502. The
%u conversion specifier prints the arguments as unsigned integers.

Recollect that an integer occupies 2 bytes of memory. Hence, value of var is stored at 65500 and the
compiler allots the next memory allocation 65502 to ptr_var. Similarly, a floating point number will
require four bytes and a double precision number may require eight bytes. Pointer variables store an
integer value. For most programs using pointers, pointer types can be considered to be 16-bit values that
occupy 2 bytes.

Note that the following two statements give the same output.

printf(“The value is %d”, var);


printf(“The value is %d”, *(&var));

page 206 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

Assigning Values to Pointers

Concepts
Values can be assigned to pointers through the & operator. The assignment statement will be:

ptr_var = &var;

where the address of var is stored in the variable ptr_var. It is also possible to assign values to
pointers through another pointer variable pointing to a data item of the same type.

ptr_var = &var;
ptr_var2 = ptr_var;

A NULL value can also be assigned to a pointer using zero as follows:

ptr_var = 0;

Variables can be assigned value through their pointers as well.

*ptr_var = 10;

will assign 10 to the variable var if ptr_var points to var.

In general, expressions involving pointers follow the same rules as other C expressions. It is very important
to assign values to pointer variables before using them; else they could be pointing to any unpredictable
values.

Pointer Arithmetic

Addition and subtraction are the only operations, which can be performed on pointers. The following
example demonstrates this:

int var, *ptr_var;


ptr_var = &var;
var = 500;

In the above example, let us assume that var is stored at the address 1000. Then, ptr_var has the
value 1000 stored in it. Since integers are 2 bytes long, after the expression:

ptr_var++ ;

ptr_var will contain 1002 and NOT 1001. This means that ptr_var is now pointing to the integer
stored at the address 1002. Each time ptr_var is incremented, it will point to the next integer and since

Elementary Programming with C Version 1.1 © Aptech Limited page 207 of 356
Session 13
Pointers

integers are 2 bytes long, ptr_var will be incremented by 2. The same is true for decrements also.
Concepts

Here are few more examples.

++ptr_var or ptr_var++ points to next integer after var


--ptr_var or ptr_var-- points to integer previous to var
ptr_var + i points to the ith integer after var
ptr_var – i points to the ith integer before var
++*ptr_var or (*ptr_var)++ Will increment var by 1
*ptr_var++ Will fetch the value of the next integer after var

Each time a pointer is incremented, it points to the memory location of the next element of its base
type. Each time it is decremented, it points to the location of the previous element. With pointers to
characters, this appears normal, because generally characters occupy 1 byte per character. However, all
other pointers will increase or decrease depending on the length of the data type they are pointing to.

As seen in the above examples, in addition to the increment and decrement operators, integers can be
added and subtracted to or from pointers. Besides addition and subtraction of a pointer and an integer,
none of the other arithmetic operations can be performed on pointers. To be specific, pointers cannot be
multiplied or divided. Also, float or double type cannot be added or subtracted to or from pointers.

Pointer Comparisons

Two pointers can be compared in a relational expression. However, this is possible only if both these
variables are pointing to variables of the same type. Consider that ptr_a and ptr_b are two pointer
variables, which point to data elements a and b. In this case, the following comparisons are possible:

ptr_a < ptr_b Returns true provided a is stored before b


ptr_a > ptr_b Returns true provided a is stored after b
ptr_a <= ptr_b Returns true provided a is stored before b or ptr_a and ptr_b point
to the same location
ptr_a >= ptr_b Returns true provided a is stored after b or ptr_a and ptr_b point to
the same location
ptr_a == ptr_b Returns true provided both pointers ptr_a and ptr_b points to the
same data element
ptr_a != ptr_b Returns true provided both pointers ptr_a and ptr_b point to different
data elements but of the same type
ptr_a == NULL Returns true if ptr_a is assigned NULL value (zero)

Also, if ptr_begin and ptr_end point to members of the same array then,

ptr_end - ptr_begin

page 208 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

will give the difference in bytes between the storage locations to which they point.

Concepts
13.4 Pointers and Single-dimensional Arrays

An array name is truly a pointer to the first element in that array. Therefore, if ary is a single-dimensional
array, the address of the first array element can be expressed as either &ary[0] or simply as ary.
Similarly, the address of the second array element can be written as &ary[1] or as ary+1, and so on.
In general, the address of the (i + 1)th array element can be expressed as either & ary[i] or as (ary
+ i). Thus, the address of an array element can be expressed in two ways:

 By writing the actual array element preceded by the ampersand sign (&)

 By writing an expression in which the subscript is added to the array name

Remember that in the expression (ary + i), ary represents an address, whereas i represents an
integer quantity. Moreover, ary is the name of an array whose elements can be both integers, characters,
floating point, and so on (of course, all elements have to be of the same type). Therefore, the above
expression is not a mere addition; it is actually specifying an address, which is a certain number of
memory cells beyond the first. The expression (ary + i) is in true sense, a symbolic representation for
an address specification rather than an arithmetic expression.

As said before, the number of memory cells associated with an array element will depend on the data
type of the array as well as the computer’s architecture. However, the programmer can specify only the
address of the first array element that is the name of the array (ary in this case) and the number of array
elements beyond the first, that is, a value for the subscript. The value of i is sometimes referred to as an
offset when used in this manner.

The expressions &ary[i] and (ary + i) both represent the address of the ith element of ary, and so it
is only logical that ary[i] and *(ary + i) both represent the contents of that address, that is, the value
of the ith element of ary. Both terms are interchangeable and can be used in any particular application
as desired by the programmer.

The following program shows the relationship between array elements and their addresses.

Example 2:

#include<stdio.h>
void main()
{
static int ary[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int i;
for (i = 0; i < 10; i ++)
{

Elementary Programming with C Version 1.1 © Aptech Limited page 209 of 356
Session 13
Pointers

printf(“\n i = %d , ary[i] = %d , *(ary+i)= %d “, i, ary[i], *(ary


+ i));
Concepts

printf(“&ary[i] = %X , ary + i = %X”, &ary[i], ary+i);


/* %X gives unsigned hexadecimal */
}
}

The above program defines a single dimensional, 10-element integer array ary, whose elements are
assigned the values 1, 2, ..10. The for loop is used to display the value and the corresponding address
of each array element. Note that the value of each element is specified in two different ways, as ary[i]
and as *(ary + i), to illustrate their equivalence. Similarly, the address of each array element is also
displayed in two ways. The output of the program will be as follows:

i=0 ary[i]=1 *(ary+i)=1 &ary[i]=194 ary+i = 194


i=1 ary[i]=2 *(ary+i)=2 &ary[i]=196 ary+i = 196
i=2 ary[i]=3 *(ary+i)=3 &ary[i]=198 ary+i = 198
i=3 ary[i]=4 *(ary+i)=4 &ary[i]=19A ary+i = 19A
i=4 ary[i]=5 *(ary+i)=5 &ary[i]=19C ary+i = 19C
i=5 ary[i]=6 *(ary+i)=6 &ary[i]=19E ary+i = 19E
i=6 ary[i]=7 *(ary+i)=7 &ary[i]=1A0 ary+i = 1A0
i=7 ary[i]=8 *(ary+i)=8 &ary[i]=1A2 ary+i = 1A2
i=8 ary[i]=9 *(ary+i)=9 &ary[i]=1A4 ary+i = 1A4
i=9 ary[i]=10 *(ary+i)=10 &ary[i]=1A6 ary+i = 1A6

This output clearly shows the difference between ary[i], which represents the value of the ith array
element, and &ary[i], which represents its address.

When assigning a value to an array element such as ary[i], the left side of the assignment statement
can be written as either ary[i] or as *(ary + i). Thus, a value may be assigned directly to an array
element or it may be assigned to the memory area whose address is that of the array element. It is
sometimes necessary to assign an address to an identifier. In such situations, a pointer must appear
on the left side of the assignment statement. It is not possible to assign an arbitrary address to an array
name or to an array element. Thus, expressions such as ary, (ary + i) and &ary[i] cannot appear
on the left side of an assignment statement. Moreover, the address of an array cannot be arbitrarily
altered, so expressions such as ary++ are not allowed. The reason for this is: ary is the address of the
array ary. When the array is declared, the linker has decided where this array will go, for example, say
an address 1002. Once it is given this address, it stays there. Trying to increment this address has no
meaning, its like saying

x = 5++;

Since a constant cannot be incremented, the compiler will flag an error.

page 210 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

In case of the array ary, ary is also known as a Pointer Constant. Remember, (ary + 1) does not
move the array ary to the (ary + 1)th position, it just points to that position, whereas ary++ actually

Concepts
tries to move ary by 1 position.

The address of one element cannot be assigned to some other array element, though the value of one
array element can be assigned to another through pointers.

&ary[2] = &ary[3]; /* not allowed */


ary[2] = ary[3]; /* allowed */

Recall that the scanf() function required that variables of the basic data types be preceded by ampersands
(&), whereas array names were exempted from this requirement. This will be easy to understand now.
The scanf() requires that the address of the data items, being entered into the computer’s memory,
be specified. As said before, the ampersand (&) actually gives the address of the variable and so it is
required that an ampersand precede a single valued variable. Ampersands are not required with array
names because array names themselves represent addresses. However, if a single element of an array
is to be read, it will require an ampersand to precede it.

scanf(“d”, *ary) /* For first element of array */


scanf(“%d”, &ary[2]) /* For an array element */

13.4.1 Pointers and Multidimensional Arrays

The way a single dimensional array can be represented in terms of a pointer (the array name) and an offset
(the subscript), a multidimensional array can also be represented with an equivalent pointer notation. This
is because a multidimensional array is actually a collection of single dimensional arrays. For example, a
two-dimensional array can be defined as a pointer to a group of contiguous one-dimensional arrays. A
two-dimensional array declaration can be written as:

data_type (*ptr_var)[expr 2];

instead of

data_type array[expr 1][expr 2];

This concept can be generalized to higher dimensional arrays, that is,

data_type (*ptr_var)[exp 2] .... [exp N];

can be written instead of

data_type array[exp 1][exp 2] ... [exp N];

Elementary Programming with C Version 1.1 © Aptech Limited page 211 of 356
Session 13
Pointers

In these declarations, data_type refers to the data type of the array, ptr_var is the name of the
pointer variable, array is the corresponding array name, and exp 1, exp 2, exp 3, ... exp N are positive
Concepts

valued integer expressions that indicate the maximum number of array elements associated with each
subscript.

Note the parentheses that surround the array name and the preceding asterisk in the pointer version of
each declaration. These parentheses must be present; else the definition would represent an array of
pointers rather than a pointer to a group of arrays.

For example, if ary is a two dimensional array having 10 rows and 20 columns, it can be declared as

int (*ary)[20];

instead of

int ary[10][20];

In the first definition, ary is defined to be a pointer to a group of contiguous, single-dimensional, 20-
element integer arrays. Thus, ary points to the first element of the array, which is actually the first row
(row 0) of the original two-dimensional array. Similarly, (ary + 1) points to the second row of the original
two-dimensional array, and so on.

A three-dimensional floating-point array fl_ary can be defined as:

float (*fl_ary)[20][30];

rather than

float fl_ary[10][20][30];

In the first declaration, fl_ary is defined as a group of contiguous, two-dimensional, 20 x 30 floating point
arrays. Hence, fl_ary points to the first 20 x 30 array, (fl_ary + 1) points to the second 20 x 30 array,
and so on.

In the two-dimensional array ary, the item in row 4 and column 9 can be accessed using the statement:

ary[3][8];

or

*(*(ary + 3) + 8);

The first form is the usual way in which an array is referred to. In the second form, (ary + 3) is a pointer

page 212 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

to the row 4. Therefore, the object of this pointer, *(ary + 3), refers to the entire row. Since row 3 is
a one-dimensional array, *(ary + 3) is actually a pointer to the first element in row 3, 8 is then added

Concepts
to this pointer. Hence, *(*(ary + 3) + 8) is a pointer to element 8 (the 9th element) in row 4. The
object of this pointer, *(*(ary + 3) + 8), therefore refers to the item in column 9 of row 4, which is ary
[3][8].

There are different ways to define arrays, and different ways to process the individual array elements. The
choice of one method over another generally depends on the user’s preference. However, in applications
involving numerical arrays, it is often easier to define the arrays in the conventional manner.

Pointers and Strings

Strings are nothing but single-dimensional arrays, and as arrays and pointers are closely related, it is only
natural that strings too will be closely related to pointers. Consider the case of the function strchr().
This function takes as arguments a string and a character to be searched for in that string, that is,

ptr_str = strchr(strl, ‘a’);

the pointer variable ptr_str will be assigned the address of the first occurrence of the character ‘a’ in
the string str. This is not the position in the string, from 0 to the end of the string but the address, from
where the string starts to the end of the string.

The following program uses strchr() in a program which allows a user to enter a string and a character
to be searched for. The program prints out the address of the start of the string, the address of the
character, and the character’s position relative to the start of the string (0 if it is the first character, 1 if it is
the second and so on). This relative position is the difference between the two addresses, the address of
start of the string and the address where the character’s first occurrence is found.

Example 3:

#include <stdio.h>
#include <string.h>
void main ()
{
char a, str[81], *ptr;
printf(“\nEnter a sentence:”);
gets(str);
printf(“\nEnter character to search for:”);
a = getchar();
ptr = strchr(str,a);
/* return pointer to char */
printf( “\nString starts at address: %u”,str);
printf(“\nFirst occurrence of the character is at address: %u”, ptr);

Elementary Programming with C Version 1.1 © Aptech Limited page 213 of 356
Session 13
Pointers

printf(“\n Position of first occurrence (starting from 0)is: %d”, ptr-


str);
Concepts

A sample run will be as follows:

Enter a sentence: We all live in a yellow submarine


Enter character to search for: Y
String starts at address: 65420.
First occurrence of the character is at address: 65437.
Position of first occurrence (starting from 0) is: 17

In the declaration statement, a pointer variable ptr is set aside to hold the address returned by strchr(),
since this is an address of a character (ptr is of type char).

The function strchr() does not need to be declared if the include file string.h is included.

13.5 Allocating Memory

Till this point of time it has been established that an array name is actually a pointer to the first element of
the array. Also, it is possible to define the array as a pointer variable rather than the conventional array.
However, if an array is declared conventionally, it results in a fixed block of memory being reserved at
the beginning of the program execution, whereas this does not occur if the array is represented as a
pointer variable. As a result, the use of a pointer variable to represent an array requires some sort of initial
memory assignment before the array elements are processed. Such memory allocations are generally
done using the malloc() library function.

Consider an example. A single dimensional integer array ary having 20 elements can be defined as:

int *ary;

instead of

int ary[20];

However, ary will not be automatically assigned a memory block when it is defined as a pointer variable,
though a block of memory enough to store 10 integer quantities will be reserved in advance if ary is
defined as an array. If ary is defined as a pointer, sufficient memory can be assigned as follows:

ary = malloc(20 *sizeof(int));

This will reserve a block of memory whose size (in bytes) is equivalent to the size of an integer. Here,

page 214 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

a block of memory for 20 integers is allocated. The number 20 assigns 20 bytes (one for each integer)
and this is multiplied by sizeof(int), which will return 2, if the computer uses 2 bytes to store an

Concepts
integer. If a computer uses 1 byte to store an integer, the sizeof() function is not required. However,
it is preferable to use this always as it facilitates the portability of code. The function malloc() returns
a pointer which is the address location of the starting point of the memory allocated. If enough memory
space does not exist, malloc() returns a NULL. The allocation of memory in this manner, that is, as and
when required in a program is known as Dynamic memory allocation.

Before proceeding further, let us discuss the concept of Dynamic Memory allocation. A C program can
store information in the main memory of the computer in two primary ways. The first method involves
global and local variables – including arrays. In the case of global and static variables, the storage is
fixed throughout the program’s run time. These variables require that the programmer knows the amount
of memory needed for every situation in advance. The second way in which information can be stored is
through C’s Dynamic Allocation System. In this method, storage for information is allocated from the
pool of free memory as and when needed.

The malloc() function is one of the most commonly used functions which permit allocation of memory
from the pool of free memory. The parameter for malloc() is an integer that specifies the number of
bytes needed.

As another example, consider a two-dimensional character array ch_ary having 10 rows and 20 columns.
The definition and allocation of memory in this case would be as follows:

char (*ch_ary)[20];
ch_ary = (char*)malloc(10*20*sizeof(char));

As said earlier, malloc() returns a pointer to type void. However, since ch_ary is a pointer to type
char, type casting is necessary. In the above statement, (char*) casts malloc() so as to return a
pointer to type char.

However, if the declaration of array has to include the assignment of initial values then an array has to be
defined in the conventional manner rather than as a pointer variable as in:

int ary[10] = {1,2,3,4,5,6,7,8,9,10};

or

int ary[] = {1,2,3,4,5,6,7,8,9,10};

The following example creates a single dimensional array dynamically and sorts the array in ascending
order. It uses pointers and the malloc() function to assign memory.

Elementary Programming with C Version 1.1 © Aptech Limited page 215 of 356
Session 13
Pointers

Example 4:
Concepts

#include<stdio.h>
#include<malloc.h>
void main()
{
int *p,n,i,j,temp;
printf(“\n Enter number of elements in the array :”);
scanf(“%d”,&n);
p=(int*)malloc(n*sizeof(int));
for(i=0;i<n;++i)
{
printf(“\nEnter element no. %d:”,i+1);
scanf(“%d”,p+i);
}
for(i=0;i<n-1;++i)
for(j=i+1;j<n;++j)
if(*(p+i)>*(p+j))
{
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
for(i=0;i<n;++i)
printf(“%d\n”,*(p+i));
}

Note the malloc() statement,

p = (int*)malloc(n*sizeof(int));

Here, p is declared as a pointer to an array and assigned an amount of memory using malloc().

Data is read, using scanf().

scanf(“%d”,p+i);

In scanf(), the pointer variable is used to store data into the array.

Sorted array elements are displayed using printf().

page 216 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

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

Concepts
Note the asterisk in this case. This is because the value stored in that particular location has to be
displayed. Without the asterisk, the printf() will display the address where the marks are stored and
not the marks stored.

 free()

This function can be used to de-allocate (frees) memory when it is no longer needed.

The general format of free() function:

voidfree( void *ptr );

The free() function de-allocates the space pointed to by ptr, freeing it up for future use. ptr
must have been used in a previous call to malloc(), calloc(), or realloc(). calloc() and
realloc() have been discussed later.

The example given below will ask you how many integers you’d like to store in an array. It’ll then
allocate the memory dynamically using malloc() and store a certain number of integers, print
them out, then releases the used memory using free.

Example 5:

#include <stdio.h>
#include <stdlib.h> /* required for the malloc and free functions */
int main()
{
int number;
int *ptr;
int i;
printf(“How many ints would you like store? “);
scanf(“%d”, &number);
ptr = (int *) malloc (number*sizeof(int)); /* allocate memory */
if(ptr!=NULL)
{
for(i=0 ; i<number ; i++)
{
*(ptr+i) = i;
}

Elementary Programming with C Version 1.1 © Aptech Limited page 217 of 356
Session 13
Pointers

for(i=number ; i>0 ; i--)


Concepts

{
printf(”%d\n”,*(ptr+(i-1))); /* print out in reverse order
*/
}
free(ptr); /* free allocated memory */
return 0;
}
else
{
printf(”\nMemory allocation failed - not enough memory.\n”);
return 1;
}
}

Output if entered 3:

How many ints would you like store? 3


2
1
0

 calloc()

calloc is similar to malloc, but the main difference is that the values stored in the allocated
memory space is zero by default. With malloc, the allocated memory could have any value.

calloc requires two arguments. The first is the number of variables you’d like to allocate memory
for. The second is the size of each variable.

void *calloc( size_t num, size_t size );

Like malloc, calloc will return a void pointer if the memory allocation was successful, else it will
return a NULL pointer.

The example given below shows you how to call calloc and reference the allocated memory
using an array index. The initial value of the allocated memory is printed out in the for loop.

page 218 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

Example 6:

Concepts
#include <stdio.h>
#include <stdlib.h>
int main()
{
float *calloc1, *calloc2;
int i;
calloc1 = (float *) calloc(3, sizeof(float));
calloc2 = (float *)calloc(3, sizeof(float));
if(calloc1!=NULL && calloc2!=NULL)
{
for(i=0 ; i<3 ; i++)
{
printf(”calloc1[%d] holds %05.5f ”, i, calloc1[i]);
printf(”\ncalloc2[%d] holds %05.5f ”, i, *(calloc2+i));
}
free(calloc1);
free(calloc2);
return 0;
}
else
{
printf(”Not enough memory\n”);
return 1;
}
}

Output:

calloc1[0] holds 0.00000


calloc2[0] holds 0.00000
calloc1[1] holds 0.00000
calloc2[1] holds 0.00000
calloc1[2] holds 0.00000
calloc2[2] holds 0.00000

On all machines, the calloc1 and calloc2 arrays should hold zeros. calloc is especially useful
when you’re using multi-dimensional arrays. Here is another example to demonstrate the use of
calloc() function.

Elementary Programming with C Version 1.1 © Aptech Limited page 219 of 356
Session 13
Pointers

Example 7:
Concepts

/* This program gets the number of elements, allocates spaces for the
elements, gets a value for each element, sum the values of the elements,
and print the number of the elements and the sum.
*/
#include <stdio.h>
#include <stdlib.h>
main()
{
int *a, i, n, sum = 0;
printf ( “\n%s%s”, “An array will be created dynamically. \n\n”,
“Input an array size n followed by integers : ” );
scanf( “%d”, &n); /* get the number of elements */
a = (int *) calloc (n, sizeof(int) ); /* allocate space */
/* get a value for each element */
for( i = 0; i < n; i++ )
{
printf(“Enter %d values : “,n);
scanf( “%d”, a + i );
}
/* sum the values */
for(i = 0; i < n; i++ )
sum += a[i];
free(a); /* free the space */
/* print the number and the sum */
printf ( “\n%s%7d\n%s%7d\n\n”, “Number of elements: ”, n, “Sum of
the elements: ”, sum );
}

 realloc()

Suppose you’ve allocated a certain number of bytes for an array but later find that you want to add
values to it. You could copy everything into a larger array, which is inefficient, or you can allocate
more bytes using realloc, without losing your data.

realloc() takes two arguments. The first is the pointer referencing the memory. The second is
the total number of bytes you want to reallocate.

void *realloc( void *ptr, size_t size );

page 220 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

Passing zero as the second argument is the equivalent of calling free.

Concepts
Once again, realloc returns a void pointer if successful, else a NULL pointer is returned.

This example uses calloc to allocate enough memory for an int array of five elements. Then
realloc is called to extend the array to hold seven elements.

Example 8:

#include<stdio.h>
#include <stdlib.h>
int main()
{
int *ptr;
int i;
ptr = (int *)calloc(5, sizeof(int *));
if(ptr!=NULL)
{
*ptr = 1;
*(ptr+1) = 2;
ptr[2] = 4;
ptr[3] = 8;
ptr[4] = 16;
/* ptr[5] = 32; wouldn’t assign anything */
ptr = (int *)realloc(ptr, 7*sizeof(int));
if(ptr!=NULL)
{
printf(“Now allocating more memory... \n”);
ptr[5] = 32; /* now it’s legal! */
ptr[6] = 64;
for(i=0;i<7;i++)
{
printf(”ptr[%d] holds %d\n”, i, ptr[i]);
}
realloc(ptr,0); /* same as free(ptr); - just fancier! */
return 0;
}
else
{

Elementary Programming with C Version 1.1 © Aptech Limited page 221 of 356
Session 13
Pointers

printf(”Not enough memory - realloc failed.\n”);


Concepts

return 1;
}
}
else
{
printf(”Not enough memory - calloc failed.\n”);
return 1;
}
}

Output :

Now allocating more memory...

ptr[0] holds 1
ptr[1] holds 2
ptr[2] holds 4
ptr[3] holds 8
ptr[4] holds 16
ptr[5] holds 32
ptr[6] holds 64

Notice the two different methods that used when initializing the array: ptr[2] = 4; is the
equivalent to *(ptr+2) = 4; (just easier to read!).

Before using realloc, assigning a value to ptr[5] wouldn’t cause a compile error. The program
would still run, but ptr[5] wouldn’t hold the value you assigned.

page 222 of 356 Version 1.1 © Aptech Limited Elementary Programming with C
Session 13
Pointers

Summary

Concepts
 A pointer provides a way of accessing a variable without referring to the variable directly.

 A pointer is a variable, which contains the address of a memory location of another


variable, rather than its stored value.

 A pointer declaration consists of a base type, an *, and the variable name.

 There are two special operators which are used with pointers: * and &.

 The & operator returns the memory address of the operand.

 The second operator, *, is the complement of &. It returns the value contained in the
memory location pointed to by the pointer variable’s value.

 Addition and subtraction are the only operations, which can be performed on pointers.

 Two pointers can be compared in a relational expression only if both these variables are
pointing to variable(s) of the same type.

 Pointers are passed to a function as arguments, enabling data items within the called
routine of the program to access variables whose scope does not extend beyond the
calling function.

 An array name is truly a pointer to the first element in that array.

 A pointer constant is an address; a pointer variable is a place to store addresses.

 Memory can be allocated as and when needed by using the malloc(), calloc(), and realloc()
functions. Allocating memory in this way is known as Dynamic Memory Allocation.

Elementary Programming with C Version 1.1 © Aptech Limited page 223 of 356
Session 13
Pointers

Check Your Progress


Concepts

1. A _________ provides a way of accessing a variable without referring to the variable


directly.

A. Array B. Pointer

C. Structure D. None of the above

2. Pointers cannot point to arrays. (T/F)

3. The __________ of the pointer defines what type of variables the pointer can point to.

A. Type B. Size

C. Content D. None of the above

4. The two special operators used with pointers are ____ and _____.

A. ^ and % B. ; and ?

C. * and & D. None of the above

5. ________ and __________ are the only operations, which can be performed on
pointers.

A. Addition, Subtraction B. Multiplication, Division

C. Division, Addition D. None of the above

6. Two pointers can be compared only if both these variables are pointing to variables of
different types. (T/F)

7. The allocation of memory in this manner, that is, as and when required in a program is
known as __________ .

A. Dynamic Memory Allocation B. Static Memory Allocation

C. Content Memory Allocation D. None of the above

page 224 of 356 Version 1.1 © Aptech Limited Elementary Programming with C

You might also like