Friday, August 21, 2009

Using pointers for double dimension memory allocation OR Dynamic Memory allocation for Multidimension Array

Many times you need to allocate dynamic memory for a multidimensional array in C language. This article deals with using pointers for dynamic memory allocation for two dimensional array , which can further be extended for higher dimensions.

Example of situation when u require 2-D dynamic allocation :

1. Take the input dimension of an matrix form the user and then get input values and print them.

2. Print a magic square after taking dimensions form user.

3. Implementing Hash Table after taking hash value form user.

I will try to explain the concept by solving the first problem (simply coz its the easy to solve :) and also for others to understand )

Problem Statement : Take the input dimension of an matrix form the user and then get input values and print them.

Solution :

first i will paste a working solution and the explain it :

i tried to copy paste the code but it gave some html error ... so im pasting the image ..... will soon find some way to post the code :)

please right click and open the image in a tab to see the code


Explanation :

Problem is we need to take input from the user at run time , so we cannot declare a 2-D array of fixed dimensions before hand , we need to do it at runtime , using dynamic memory allocation.

For this we use the concept of pointer to a pointer or Double pointer.

Now to revise the basics we can use a normal pointer to allocate memory for an array , i.e. a single dimension array. It can be done in following manner.

int *array;
int arraysize;
printf("enter the size of array");
scanf("%d ",&arraysize);

array=(int *)(malloc(sizeof(int)*arraysize));

what happened above is when i said int *array a pointer named array was assigned to point to a location where some int is supposed to reside. But by writing

array=(int *)(malloc(sizeof(int)*arraysize)) i have allocated memory dynamically equal to the arraysize given by the user, where each element is integer type.

if we analyze the right hand side of the statement:

array=(int *)(malloc(sizeof(int)*arraysize));

(int*)
typecast the memory allocated to be a pointer to a integer, since array is of that type .

malloc(sizeof(int)*arraysize)
dynamically allocates a memory of elements equal to arraysize and each element of size int , since sizeof(int) is used.

so in the end what we have is a single dimension array, whose base address is pointed by pointer array.

Now coming to the code that i have posted above for 2-D array :

the part of the code that deals with the 2-D dynamic allocation is :



these three lines are the only lines which u need to understand to get the concept :

Line 1: matrix=(int**)(malloc(sizeof(int*)*no_of_rows));

The variable matrix which is a integer pointer to a pointer is allocated memory allocated equal to no_of_rows and each of type pointer to an integer. So what we have now is an Array of integer Pointers of size equal to no_of_rows .

since matrix is a double pointer so we need to typecast the memory allocated to its type by (int**) and since we are allocating memory for array of pointers so we use sizeof(int*)
.

Line 2 :


this is a simple for loop which is responsible to run the line below it no_of_rows time, so that each integer pointer from Array of Pointer can point to integer array itself .

Line 3 : *(matrix+i)=(int*)(malloc(sizeof(int)*no_of_column));

By *(matrix+i) we go to each integer pointer in the array of pointers for which we allocated memory in the Line: 1.

By (int*)(malloc(sizeof(int)*no_of_column)) we first typecast the allocated memory since *(matrix+i) is of type integer pointer we use (int*)
and now we want to store integers in the allocated space to we use sizeof(int) .

That all the memory is allocated, rest of program is simple input and display.

For any more clarification feel free to comment.










Thursday, August 20, 2009

Format USB drive / Pen Drive on LINUX - Ubuntu

Step 1:
insert the pendrive in the USB port and wait for it to be detected (or mounted according to Linux)

once it is mounted (ie it opens in a window) , go to the terminal and type the following command :

$ df -h

it will display the list of all mounted drives on your system. It will look something like image shown below :


now very carefully note the path for your pendrive , it would be written in front of the name of your pendrive. Like in above example the data to be noted is /dev/sdb

it might be in your case something else like /dev/sd1
Note: be very sure that you get the correct name otherwise you will end up formatting some other drive

Step 2:

Unmount the USB or Pendrive.
It can be done in two ways :

1. simply right click on pendrive icon on desktop and unmount.
or by
2.form terminal run following command :

$ sudo umount /dev/sdb

i prefer the second method since if pendrive is unmounted after command you can be sure you got the correct drive name in step 1.

Remember : you r only supposed to unmount the pendrive not to remove form the usb port.

Step 3 :

run the following command from the terminal :

$ sudo mkfs.vfat -I /dev/sdb

which will format the pendrive. If you want to provide and label or name to ur pendrive use following :

$ sudo mkfs.vfat -n "name/label" -I /dev/sdb

replace
"name/label" with the name u want to give to usb drive
Now ur pendrive is formatted.

Note: u can format in any file system u wish to by replacing vfat by that name example ext3 .

Wednesday, August 19, 2009

Difference between NULL and NUL

Difference Between NUL and NULL in C Language :

Hi Everyone.....

i seems no matter how much C language you learn it seems it will never end....
i found a very interesting difference between NUL and NULL in C language while going through a book which i would like to share:

NULL is an pointer with value zero (0) , that is you can say it does not correspond to a real memory location in your program. For linux operating system it is defined as ((void *)(0)) .

Whereas NUL is an character with integer value 0 (zero) . It is this NUL character you keep hearing about which comes at the end of every string as "\0" or "(char)(0)" and takes a memory space equal to that of a character .

so to remember NULL is a pointer and NUL is a character :)

Compiling Linux Kernel

Note : The following steps were for successful compilation of linux kernel 2.6.30 on the system running with Ubuntu-8.04 with Linux kernel 2.6.24 already present

Step 1:
You will need to install ncurses on your system if it is not already present. It provides a gui interface for the configuration of the kernel.

The latest version can be downloaded from the link :

http://www.gnu.org/software/ncurses/

untar the package and then from the top source directory type the following commands :

$ ./configure –without-cxx-binding
$ make
$ sudo make install


Step 2 :
Download the linux source code for kernel 2.6.30 from the below link :

http://www.kernel.org/pub/linux/kernel/v2.6/

also make sure you have gcc installed on you linux system .




Step 3 :
As root user copy the tar folder in the /usr/src directory and then untar it . For example if you have saved the .tar file on your desktop you can type the following commands current directory being Desktop :

$ sudo bash
~# cp linux-2.6.30.tar.gz /usr/src/
~# cd /usr/src
~# tar -xvvzf linux-2.6.30.tar.gz
~# cd linux-2.6.30




Step 4 :
from the top source directory of linux kernel folder type the following into terminal :
this will open an GUI , form which you can configue the kernel.
You can simply choose the default options by pressing esc two times :

~# make menuconfig



Step 5 :
Now after configure , to compile the kernel run the following command :

~# make

Step 6 :
for compilation for modules :

~# make modules

Step 7:
To install the kernel follow the following :

~# make modules_install
~# make install

Step 8:
Now the bzImage of the kernel is created which is the bunzipped compressed
image. Copy this image to boot directory by the following command :

~# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.30






Step 9:
To provide the capability to load a RAM disk by the boot loader run the following command form the terminal . At boot time, the kernel unpacks the created archive into a RAM-based disk, which is then mounted and used at the initial root filesystem. Much of the kernel initialization and bootstrap code can then be moved into this disk and run in user mode. Tasks like finding the real root disk, boot-time networking setup, handling of initrd-style ramdisks, ACPI setup, etc. will be shifted out of the kernel in this way.

~# cd /boot
~# mkinitramfs -o initrd.img-2.6.30 2.6.30



Step 10 :
Every thing is done , now update your grub according to the new kernel :
~# update-grub

Step 11 :
To see the changes run the following command :
~# vim /boot/grub/menu.lst


Go down the screen you will find entries which look like following :




As you can see the “Default” and the “recovery mode” does not have the initrd entry, but the third one , the normal kernel entry has it for kernel 2.6.30 , just copy paste the initrd entry from the third configuration and place it at the corrosponding place in the first kernel entry. After which the file will look like following :


for those who are new to vim editor , you can go to insert mode by pressing “i” and then simply copy paste.
To save the changes type the following after pressing “esc” :

~# :wq
You will now come back to the terminal.
That,s it , now simply restart you system. The new kernel entries should show in the Grub menu when you start the system. Select the new kernel that you have installed and start enjoying .

Step 12:
To check wether you are really running the new kernel or not just run the following command from the terminal :
$ cat /proc/version
you will see the deatils of the kernel being run at present.
Like in my system it showed as :

C program with NO main() function

Reason for Linux Source Code not containing a “main function”

To understand why some C programs does not require a main() function it is necessary to understand concept called Execution Environment :

Execution Environment:

Whenever we write a piece of C code we do it in an environment known as Execution Environment.

According to C standards the Execution environment includes the characteristics of the processor that will execute the program image (instruction set, number of registers, memory access characteristics, etc.), and the runtime interface to the host environment (storage allocation, function calling conventions, etc.).

In C there are basically two types of execution environments
1. Hosted environment
2. Freestanding environment

Hosted Environment:

Hosted environment is one which a normal developer encounters everyday while writing a piece of code. It already provides inbuilt support of most of the standard libraries and functions. In Hosted environment the developer does not need to worry about the basic
functionally required eg I/O functionality provided by “stdio.h” . GCC is one such platform which provides a Hosted environment which may itself be running on any OS like Linux. Andalso starting point of any hosted environment is the “main function”. Implementations use a variety of techniques to start executing a program image. These usually involve executing some internal, implementation-specific, function before main is called. Then association between this internal function and main is usually made at link-time by having the internal function make a call to “main function “, which is resolved by the
linker in the same way as other function calls. To sum-up hosted environment provides a lot of standard library functions which may or may not be needed by developer but are provided by default.

Freestanding Environment:

Freestanding environment on the other hand is intended to interact directly with the hardware. A freestanding environment does not require any built in library functions. A freestanding implementation is one in which execution may take place without the benefit of an operating system, and has an implementation-defined set of libraries that include certain language-support libraries

Why no “main function” in Linux kernel source code:

In a free standing environment there is no standardize place to begin the execution of the code. In many cases there is no named program at all. Switching on, or resetting, the freestanding host causes the processor instruction pointer to be set to some predefined location in storage, whichever instructions are located at that and subsequent locations being executed. Traditionally there is a small bootstrap loader at this location, which copies a
larger program from a storage device into memory and jumps to the start of that program (it might be a simple operating system). In other cases that storage device is ROM and the program will already be in memory at the predefined location. Translated program instructions are executed directly from the storage device. Once switched on, the host may have buttons that cause the processor to be reset to a different location, causing different
functions to be invoked on startup. For example OS kernel which itself is supposed to provide an hosting environment for
writing C code is written according to freestanding environment in mind, this is the reason there is no “main” function in Linux kernel source code .
Generally in the case on Linux the function placed at the default boot-up address is

start_kernel() .

In most of these cases the code on freestanding environment is used by developers who cannot afford to have all the unnecessary libraries or does not require them like the Embedded System developers .
However there are some libraries which are needed by both hosted and freestanding
environment . They are listed Below :



These libraries fulfil basic needs of C programming and come as a part of Standard Libraries .


About Me

My photo
Hi Friends, I am Samarth currently pursuing my Masters degree in Information Technology from International Institute of Information Technology ,Bangalore .