Chapter 1 Pointers and DMA
Chapter 1 Pointers and DMA
Application Programming
GUI, Data Base, Editors, Gaming
Network programming
Client-Server, Routing,
System Programming
OS, Compliers, Simulators,
Embedded System Programming
Cars, Missiles, Robots
Device Driver Programming
External hard Disk, Printers
Program v/s Process
hello.i
hello.s
hello.o
a.out
Applications of Pointers
Pointers
Definitions
Address space of a process in UNIX
Invalid pointers and segmentation faults
Segmentation faults Vs page faults
Pointers to basic types, Pointer to structures, Pointer to unions
Pointer initialization, significance of NULL pointer
Pointers into single dimensional integer and character arrays.
Pointer Arithmetic, addition and subtractions as defined in ISO C99
A pointer is a variable whose value is the address of another
variable that must be declared before using it to store the address of
any variable.
ptr++; // Pointer moves to the next int position (as if it was an array)
++ptr; // Pointer moves to the next int position (as if it was an array)
++*ptr; // The value of ptr is incremented
++(*ptr); // The value of ptr is incremented
*ptr++; // Pointer moves to the next int position (as if it was an array). But returns the old content
(*ptr)++; // The value of ptr is incremented
*(ptr)++; // Pointer moves to the next int position (as if it was an array). But returns the old content
*++ptr; // Pointer moves to the next int position, and then get's accessed, with your code, segfault
*(++ptr); // Pointer moves to the next int position, and then get's accessed, with your code, segfault
we perform any arithmetic function like increment on a pointer, changes occur as
per the size of their primitive data type.
Ptr1=&x; is valid
Eg. const int* ptr
Pointer to Constant Vs constant pointer
#include<stdio.h>
#include<stdio.h> #include<stdio.h>
int main(void)
int main(void) int main(void)
{ {
{ int var1 = 0,var2 = 0;
int var1 = 0; const int* const ptr = &var1;
int var1 = 0, var2 = 0;
int *const ptr = &var1; const int* ptr = &var1; *ptr = 1;
ptr = &var2; *ptr = 1; ptr = &var2;
printf("%d\n", *ptr); printf("%d\n", *ptr); printf("%d\n", *ptr);
return 0; return 0; return 0;
} } }
A constant pointer to constant is a pointer that can neither change the address its
pointing to and nor it can change the value kept at that address.
A pointer which has not been initialized to anything (not even NULL)
is known as wild pointer.
In most of the operating systems, programs are not permitted to access memory at address 0 because that
memory is reserved by the operating system. However, the memory address 0 has special significance; it
signals that the pointer is not intended to point to an accessible memory location. But by convention, if a
pointer contains the null (zero) value, it is assumed to point to nothing.
Pointer to Structure
struct Book
{
char name[10];
int price;
};
int main()
{
struct Book a; //Single structure variable
struct Book* ptr; //Pointer of Structure type
ptr = &a;
struct Book b[10]; //Array of structure variables
struct Book* p; //Pointer of Structure type
p = &b;
}
Accessing Structure Members with Pointer
To access members of structure with structure variable, we used the dot . operator. But when we have
a pointer of structure type, we use arrow -> to access structure members.
{ printf("NAME: %s\n",ptr->name);
}; }
Union
A union is a special data type available in C that allows to store
different data types in the same memory location.
You can define a union with many members, but only one member
can contain a value at any given time.
Defining a Union
To define a union, you must use the union statement in the same
way as you did while defining a structure. The union statement
defines a new data type with more than one member for the
program.
The format of the union statement is as follows −
union [union tag]
{
member definition;
member definition; ... member definition;
} [one or more union variables];
union Data
{
int i;
float f;
char str[20];
} data;
Example:
#include <stdio.h>
#include <string.h>
union Data
{
int i;
float f;
char str[20];
};
int main( )
{
union Data data;
printf( "Memory size occupied by data :%d\n“, sizeof(data));
return 0;
}
Accessing Union Members
char str[20];
};
int main( )
Note : the output will be the last inserted
{ value, others junk value
union Data data;
data.i = 10;
data.f = 220.5;
strcpy( data.str, "C Programming");
#include <stdio.h> printf( "data.str : %s\n", data.str);
#include <string.h> return 0;
union Data }
{
int i;
float f;
char str[20];
};
Note : one member is being used at a
int main( ) time.
{
union Data data;
data.i = 10;
printf( "data.i : %d\n", data.i);
data.f = 220.5;
printf( "data.f : %f\n", data.f);
strcpy( data.str, "C Programming");
Pointer and Arrays
When an array is declared, compiler allocates sufficient amount of memory to contain all the
elements of the array. Base address i.e address of the first element of the array is also allocated
by the compiler.
int arr[5] = { 1, 2, 3, 4, 5 };
Assuming that the base address of arr is 1000 and each integer requires two bytes, the five
elements will be stored as follows
Here variable arr will give the base address, which is a constant pointer pointing to the
element, arr[0]. Therefore arr is containing the address of arr[0] i.e 1000.
In short, arr has two purpose- it is the name of an array and it acts as a
pointer pointing towards the first element in the array.
int *p;
p = arr;
or p = &arr[0]; //both the statements are equivalent.
Now we can access every element of array arr using p++ to move from
one element to another.
In a[i][j], a will give the base address of this array, even a+0+0 will also
give the base address, that is the address of a[0][0] element.
Pointer can also be used to create strings. Pointer variables of char type are treated
as string. char *str = "Hello";
This creates a string and stores its address in the pointer variable str. The
pointer str now points to the first character of the string "Hello".
Another important thing to note that string created using char pointer can be
assigned a value at runtime.
char *str;
str = "hello"; //this is Legal
The content of the string can be printed using printf() and puts().
printf("%s", str);
puts(str);
Notice that str is pointer to the string, it is also name of the string. Therefore we do
not need to use indirection operator *.
Array of Pointers
We can also have array of pointers. Pointers are very helpful in handling character
array with rows of varying length.
char *name[3]={
"Adam",
"chris",
"Deniel"
};
//Now see same array without using pointer
char name[3][20]= {
"Adam",
"chris",
"Deniel"
};
In the second approach memory wastage is more, hence it is prefered to use pointer
in such cases.
Passing Pointer to a Function
When we pass a pointer as an argument instead of a variable then the address of
the variable is passed instead of the value.
So any change made by the function using the pointer is permanently made at the
address of passed variable. This technique is known as call by reference in C.
#include <stdio.h> printf("\nValue of v2 is: %d", v2);
void swapnum(int *num1, int *num2)
{ /*calling swap function*/
int tempnum; swapnum( &v1, &v2 );
int main( )
{
int v1 = 11, v2 = 77 ;
printf("Before swapping:");
printf("\nValue of v1 is: %d", v1);
Function Returning Pointer
The syntax of a function returning a pointer is as follows.
Syntax: type *function_name(type1, type2, ...);
#include<stdio.h>
int *return_pointer(int *, int); printf("Address of ptr = %u\n\n" , ptr);
// this function returns a pointer of type int printf("Value at %u is %d\n", ptr, *ptr);
// signal to operating system program ran fine
int main() return 0;
{ }
int i, *ptr;
int arr[] = {11, 22, 33, 44, 55}; int *return_pointer(int *p, int n)
i = 4; {
p = p + n;
printf("Address of arr = %u\n", arr); return p;
}
ptr = return_pointer(arr, i);
The compiler writes this information into the header of the executable file
that it creates. When the executable is loaded into memory at runtime, the
specified amount of memory is set aside.
We can create an array of pointers of size and to dynamically allocate memory for every row.
#include <stdio.h>
for (i = 0; i < r; i++)
#include <stdlib.h>
for (j = 0; j < c; j++)
arr[i][j] = ++count; // Or *(*(arr+i)+j) =
int main()
++count
{
for (i = 0; i < r; i++)
int r = 3, c = 4, i, j, count;
for (j = 0; j < c; j++)
int *arr[r];
printf("%d ", arr[i][j]);
for (i=0; i<r; i++)
/* Code for further processing and free the
arr[i] = (int *)malloc(c * sizeof(int));
dynamically allocated memory */
// Note that arr[i][j] is same as (*(arr+i)+j)
return 0;
count = 0;
}
Using pointer to a pointer
int **arr = (int **)malloc(r * sizeof(int *)); /* Code for further processing and free the
for (i=0; i<r; i++) dynamically allocated memory */
arr[i] = (int *)malloc(c * sizeof(int));
return 0;
// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
}
Using double pointer and one malloc call for all rows
#include<stdio.h>
#include<stdlib.h>
for (i = 0; i < r; i++)
int main() for (j = 0; j < c; j++)
{ arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count
int r=3, c=4;
int **arr;
int count = 0,i,j; for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr = (int **)malloc(sizeof(int *) * r); printf("%d ", arr[i][j]);
arr[0] = (int *)malloc(sizeof(int) * c * r);
return 0;
for(i = 0; i < r; i++)
arr[i] = (*arr + c * i);
}