Showing posts with label C language for Job Change. Show all posts
Showing posts with label C language for Job Change. Show all posts

Tuesday, November 24, 2015

OS : Multithread


Recently, I have one doubt over process.  I tried to understand it, but as it mostly happens to understand it I had to check something else.


https://computing.llnl.gov/tutorials/pthreads/


When we run a program, a PROCESS is created. Now each PROCESS is actually a default THREAD, which requires ONE CORE of CPU.

All this doubts came since now CPU are multiprocessor and multicore.

So when we have octa-core CPU, that means it has 8 cores. Now on this CPU we can run 8 threads at same time.

Now if no PROCESS is creating any threads, then we have 8 PROCESS running at same time on this CPU.

Now each PROCESS has its own ADDRESS SPACE.  But THREADS of same PROCESS share the ADDRESS SPACE of default THREAD of the PROCESS.


But with SINGLE CORE CPU, even when we have multiple THREADED program written, THREADS will be running one after another.

Now if we have put our THREAD into sleep or if it is waiting for some resource, then CPU will process some other THREAD based on PRIORITY.


Also please note, when you are making a multithreaded program, then you divide your FUNCTIONALITY into SUB-FUNCTIONALITY and assigns each SUB_F  to threads.

Each THREAD entry point is call to that FUNCTION.


Use Case :

1) You have to guess a word which is 4 letter and starts with W and ends with R.  Now I will give you one such word with all four letters. You have to see how fast you can reach it.

Now with multi-core CPU, we can use both CORE to work parallely to guess words.

This is when you have MULTICORE processor

2) In case of SINGLE PROCESS which has two parts, one BACKGROUND/DATA PROCESSING and ONE FOREGROUND. In this case we don't want our FOREGROUND process to be slow because of BACKGROUND.

This is use case when you have SINGLE CORE processor.

Make a program in which one THREAD writes data to text file and one THREAD is printing loop count, and one thread is calculating fibonacci series.  See when you perform READ/WRITE operation does fibonacci program runs.



-----------------------------------------------------------------------------------------------------------------------

How does THREADS get scheduled ?

Can we call some THREAD from other task ? We have thread id, but is there any API to call THREAD from the thread id.

Does Modem uses THREAD ? if yes where and why

Tuesday, October 6, 2015

C language : bitwise operator



This post is more like patchwork.

Even though most of the things has been covered, but still we can have some questions  about known things, which if not working regularly can put us in doubt.

1) Right Shift on Signed type

int a= 0x80;

a= a>>1;

// Main thing is what will happen to MSB , will it be substituted by 0 or 1.

The sign bit on right shift retains it original value , so if it was 0 , it will remain so. If it was 1 , it will remain so. 

int  a=-0x80;

a = a>>1;

2) Right Shift on Unsigned type


The MSB will be replaced by 0.

3) Left Shift on Signed Type or unsigned type

It doesn't have any effect.  Only thing to note is if for SIGNED MSB becomes 1 due to left shift, then while printing its value we should not be surprised by its negative value.


Difference between + and &. 

+ is same as &, only thing is in case of + , we carry forward .

Ex :  0011 + 0010  , in this case when we came to 2nd LSB 1+1 will give as 0 and we will carry forward the 1, In case of & NO.


While making program, I am bit surprised to see one thing.

Try to run below program and see if you can get it.

unsigned int a= -0x80;

printf("%d",a);

a = a<<1;

printf("%d",a);


When you will run this program, you will notice NEGATIVE value. But a is UNSIGNED then WHY ??


It is due to %d argument,   In C , SIGNED is default. Same was %d is for signed int, but we are accustomed to us it everywhere.

The correct format type is %u. 

C language : Memory Layout 2



Well ...I thought that the first post would be enough for this thing, but it turns out that still more is needed.


My friend was asked one question : Will the executable build on windows will work on Linux.


Offcourse the answer is NO, as we have seen many a times practically. But Why Not ?


The C code which we write is same for both, we can use the .C file and work on both the system.


So where does the difference occurs.  Is it due to Compilers  GCC vs Visual Studio.  ?


OS  Windows vs Linux ? 


So again I am trying to find out what could be the reason.




So starting first, the basic steps involved in  C code to Executable are




1)  Preprocessing :  Can I use preprocessed file or one system to another ?

2) C code to Assembly Code : Done by Compiler  :  Can I use  this code file across system ?
 
3) Assembly Code to Object Code : Done by Linker : Same question

4) Object Code to Executable : Done by Loader :




Now the first thing I will do , is have GCC on Windows , so that atleast we have same file extension .


 I installed MinGW, 


Step 1)  Install MinGW from its website. Choose only C and C++ option.
Step 2) http://stackoverflow.com/questions/25542055/mingw-c-compiler-zlib1-dll-missing-error/25542347   :  Apply changes as per 2nd option
Step 3)  C:/MinGW/bin should be present in your environmental variables.






Now once this much is done,so lets dig deeper.




On Windows , I made a small program


main.c


void main()
{
}


and  compiled using




gcc -o check main.c --save-temps   // This will save the  .I , .S , .O  and .EXE file.

Same I will be compiling on Linux,

Now it turns out thing are not so easy as I was expecting.

I will be uploading the FILES later.

The window/mingw   .I extension which is for preprocessed file differs slightly from the Linux generated preprocessed file for same code.

Even though the diff was minimal, later I can see how much difference was present.

Now the assembler file of both were different, the main difference was the function call.

In winodws  it was _main  in Linux  main.


So I copied the windows preprocessed file to Linux , and generated assembly code there.

--------Some extension and command-----------

To generated preprocessed file

gcc -E main.c -o main.i   // I is extension

To generate assembly code

gcc -S main.i -o main.s  // S is extension

To generate object code

gcc -c  main.s -o main.o  // O is extension

To generate executable

gcc -o main.o  outfile.out  // .out is extension

---------------------------------------------------------------

now when I used Windows preprocessed file and generated assembly code in Linux, the file generated was same as the assembly code file for linux.

But when I generated the object code file, it differs hugely.

WHY??????  Not having the faintest idea.

Hence I am stopping this post here, until me or someone else do further debugging.

-----------------------------------------------------------------------------------------------------------------

Some question to answer .

What is assembler ?
Difference between assembly and object code ?

there was pretty interesting post I found out.

http://stackoverflow.com/questions/28490124/reverse-engineer-assembly-code-to-c-code






Monday, October 5, 2015

C language : Bits SIGNED , UNSIGNED and thier storage.



Now we have covered most of the things related to C, but still some interviewer can surprise us by asking some question , which sometimes can confused us.




For ex : One of my friend was asked.




char C = 1;   // whether 1 will be stored or 0x31 ( ascii value of 1)


One more question was


char c=30;


for ( ; c<300;c++)
{
  printf("%d",c);
}


// What will be the output.


Now in both of these question, we have to understand how  number is stored and difference between SIGNED and UNSIGNED number storage.


First we will take only CHAR and INT, since they are easy to understand than FLOAT.


Now , when we do


char c=1;
char c='1';
int c=1;
int c='1';


We have to understand that compiler takes the hexa decimal representation of that number on RHS and then stores it.  So irrespective of int or char ,  1 will be 0x01  and '1' will be 0x31.


And again while printing the values , convert the binary number representation to hexa-decimal.
And depending on %d or %c, check the  int or character representation of the stored hexa number.




So for


char a=1;
char b='1';
int c=1;
int d='1';


printf ("%d %d %d %d",a,b,c,d); // will give  1 49  1 49




Coming to second part.  SIGNED vs UNSIGNED.


SIGNED means + and - .  By DEFAULT every  char and int which we mentioned is SIGNED.


Now taking a machine which stores  CHAR in 8 bits and INT in 32 bits.


For UNSIGNED we will have 32 bits for INT...so max value can be from 0  to 2^32  -1 , for CHAR 0 to 2^8 -1.


So what if we store some number in unsigned CHAR which is greater than  255.


Then in that case, the last 8 bits of RHS representation of number will be taking into consideration,


So  if we have   unsigned char c=256;  On printing its value we will see 0 is stored in it.


Since the number 256 binary will be


0001 0000 0000 ,  and CHAR will consider only last 8 bits we have 0 in there.


You will get WARNING at compile time though, and you can use -Werror option on compilation time, so that you don't skip the warning and get unwanted behavior in your program.


So




unsigned char c=30;


for(;c<300;c+=30)
{
printf("%d",c);
}




// This will give infinite loop, since c value at max can be 255, and once it reaches 270, the actual number stored in C will be


270  =  1 0000 1110    // taking last 8 bits   =  14 , so again the loop will run.




Now what if we assign some negative number to unsigned type.


Ex :


char c = -1;


Compiler will first convert -1 to binary, using 2's complement .
After that it will take the last 8 bits of RHS and convert back to char/int representation.


Note while printing the value the 8th bit will not be taking as SIGNED bit.
It will be treated as UNSIGNED only.




SO  printf("%d",c)    will give us  255.


------------------------------------------------------------------------------------------------------------------


2's  complement   :


-1 


1) remove the negative sign
2) convert the number to binary representation
   So   we have  0000 0001
3) Apply NOT operation.
   1111 1110
4) Add 1 now
   1111 1111
------------------------------------------------------------------------------------------------------------------
Now this number will be stored , 0xFF   will be stored in UNSIGNED CHAR, since we have defined c as UNSIGNED.






So  we are done with the UNSIGNED INT and CHAR.




Now coming to SIGNED ones, In case of SIGNED types the first LHS bit is treated as signed flag,


So


1)signed char c=0x80;
2) unsigned char c=0x80;


%d of both will give as


1)  -128
2)  128     // this is quite evident


So how  1) answer came to -128.


Now 0x80 was stored as    1000 0000
When we are doing printf,  compiler sees that this is signed bit, so it prints its two complement


number              1000 0000     // first bit is 1 , append - flag when printing
 Not operation  :0111 1111
add                                    1
                           1000 0000   = 128 




Run this program and see if you can understand the output which came.


#include<stdio.h>
int main()
{
signed char c;
c= 0x80;
printf("%d\n",c);
c= 8;
printf("%d\n",c);

c= -8;
printf("%d\n",c);

c= 511;
printf("%d\n",c);
c= 255;
printf("%d\n",c);
c= -255;
printf("%d\n",c);
}




Note when dealing with SIGNED number , remember


1) Irrespective of signed or unsigned, every negative number will be stored as 2's complement.
2) While printing, if
      the number MSB is 1 and the type is SIGNED.  2's complement will be printed with negative sign


So with SIGNED types,  storage and printing values are different, which can be highlighted with below program.






One more interesting question:


#include<stdio.h>
int main()
{
unsigned char c= -8;
signed char d = 0x80;


printf("%d \n",c);
printf("%d \n",d);


signed char e = (char) c&d;
unsigned char f = c&d;


printf("%d\n",c&d);
printf("%d \n ",e);
printf("%d \n ",f);
}


Now the output will be


248
-128
128
128
128


Exp :


in C , we will have 8 complement  since it is negative ,
 8  =  0000 1000
NOT operation :  1111 0111


Now add 1
                         1111 1000  = 248 , since it is unsigned, 248 will be printed, which is also which is in STORAGE at memory for this


In d we have  1000 0000  ( In STORAGE)
when it is printed,  since MSB is 1 , its 2 complement is taken as it is SINGED.


hence,    0111 1111
add 1     1000 0000    128  and add negative sign    -128.


Now when we perform   &  operation,  we are doing operation on


1111 1000   and  1000 0000  , since these values are in storage, so we get


1000 0000  which is 128.


Now when we perform any operation between  SIGNED and UNSINGED , the result is UNSIGNED.


hence we get 128 , but when we cast it to signed variable , again 2's complement of 0x80 will be printed , hence -128.




What if we have used  +  operation instead of  &  operation.  Try to work out.


And also what about the - operation.  HINT : - operation is nothing , but telling compiler that the number is negative, so  a-b  becomes more like   a + (b 2 complement).
----------------------------------------------------------------------------------------------------------


While making - program, I got one thing, which was bit puzzling.


Ex :


unsigned char c = -8;
signed char  d = 0x80;


unsigned char e= c-d;
printf("%d",e);
printf("%d,c-d);


The output were   120  and 376.


120 is quite eveident.


C will be in memory store as 0XF8   .
and D will be  0x80.


Now when we do  c-d ...its like  c+ (d 2 complement) which is again 0x80.


So  e will be   1 0111 1000    , but since e is just 8 bits so we have  0111 1000  = 120.


But when we do printf("%d",c-d),  printf sees %d and treat c-d as SIGNED INT , hence we get 1 0111 1000 value which is 376.


-------------------------------------------------------------------


Similarly ,


signed char d = 0x80;
signed char e = -0x80;


printf("%d", -d );
printf("%d", e );


The value will be different,  try to figure it out.








So to summarize:


Every negative number gets saved as 2 complement.
While printing , it is checked is number is signed or unsigned.
While operations , the value at the storage is taken into consideration.
















Sunday, October 4, 2015

C language : File Input and output



Here we will see some methods of file input and output. That will help in writing some good code, where we want to process file data.

Everything is type of FILE when we see OS. The stdin,stdout,stderr  all are treated as file.

We will start with the simple C code of our own copy tool.

The functions which we will see are

int putchar(int)  : Its output on stdout file , whatever int we put in it. Also it returns the same int and on error EOF.

int getchar(void) : Its reads from the standard input (stdin) and returns what is the character in integer format.

Now on gcc , if we have to read input from a file, we can use getchar function in case of scanf() and using < we can tell getchar to read data from the input file rather than stdin.

> ./program  < input.txt

Similarly if we have used putchar in our program and want to save data in some file rather then getting displayed on console, we can do

>./program > output.txt

int getc(FILE *) :  This is similar to getchar, only diff it has parameter FILE pointer, in which we can specify our file name.

int putc(int,FILE *) :  same as putchar, only we can specify the file where we want to put data.

Two more function related to File.

1)  File * fopen(filename,mode) : Mode can be "w","r","a".
2) fclose(File *)


One more thing,

till now we were using
int main(),   But what if we want to pass some arguments to main from command line, Then we will use

int main( int argc, char *argv[])

argc is count of how manu arguments were given, every argument which is given is treated as STRING.

so

>./program 1 2 3

will be treated as  4 arguments    ./argument is first  and 1,2,3 next three. We have to take care inside program whether we want to convert them to int or any other type.


Now the file copy program :

#include<stdio.h>

int main(int argc ,char *argv[])
{
   int c;
   FILE *fp1;
   FILE *fp2;
 

   fp1 = fopen(argv[1],"r");
   fp2 = fopen(argv[2],"w");
   while( (c =getc(fp1))!=EOF)
   {
     putc(c,fp2);
   }
     fclose(fp1);fclose(fp2);
}

if we create output file with name copy

> gcc -o copy  program.c

> ./copy program.c dup_copy.c  // will copy program.c  to dup_copy.c


Now we will see the STDERR file, like STDOUT it also prints output onto console. I myself was not able to find good reason for doing this.

Since first of all I am not getting any way where I can use stderr to give additional  compile errors or runtime errors .

Most of the times it works like simple printf or sprintf.

On searching I found a very good blog, which told history and usage of stderrr.

http://www.jstorimer.com/blogs/workingwithcode/7766119-when-to-use-stderr-instead-of-stdout


In case you are not interested in reading it, the brief gist is

> When we are writing programs which doesn't simply involves console output, but some other way there we can clearly see difference between STDERR and STDOUT. Since in those cases we need to analysis errors and output. And if all the output is at same place it will be difficult to separate the two.

So we will not going to go deep in STDERR, untill we get a good case to use it.

Two more ways to output and input data using file.

fprintf and fscanf  , they work same as printf and scanf.

only thing which differs is first parameter of both is FILE pointer.


So now we have seen how to read character by character and also output it to any file.

But sometimes it can be very slow, So there are two more functions provided in C, which reads line by line and also for output we have a function.

char *fgets ( char *, int , FILE *)   and int fputs(char *,File *)

No need to explain FILE pointer,

Char * pointer holds the character array, IN case of  fgets the second parameter specifies the max number of character to be read.

Also the return value of fgets is same as its first parameter. It differs when end of line is encountered.

fputs returns EOF on error , else Zero.

To understand the  return value difference ...lets make a program.

We will test it using below scenarios.

1) When in fgets we have given  numberofcharacters less than in one line.
2) When in fgets we have given numberofcharacters more than in one line.
3) fgets and fputs  return value when FILE don't exist.
4) fgets and fputs  return value when FILE is empty.

Okay , so here is learning from the program about fgets.


#include<stdio.h>

int main()
{

FILE *fp;
char *c;
char c_dup[10]={};

fp = fopen("read.txt","r");

printf("fp value %d\n ",fp);
c = fgets(c_dup,10,fp);

printf("%p \n",c);
printf("%p \n",c_dup);

printf("%s \n",c);
printf("%s \n",c_dup);
return 0;
}



1) If file doesn't exist or can't be read. Then fp will return NULL. AND we should check this value, else we will get runtime error, segmentation fault.

2) The  return value and first parameter of fgets points to same address, if some text is returned and this address is of the CHAR * pointer we passed to fgets.

3) If file is empty, then fgets will return NULL/EOF , whereas char * will be empty string. 

4) If number of characters is more than present in the line, then characters present till the end of line will be returned.

In case of fputs, even if FILE can't be open or doesn't exist, it will return -1 , if write is successful, then 1 is return

In case we want the input file to be STDIN  and output file to be STDOUT,   you can use 

int puts (char *)   and  char *gets(char *)

No need of number of character is needed for gets.




Friday, October 2, 2015

C langauge : Pointers 2

Well, while writing the second way code, I found their was bug in my code and it was very basic error, hence I moved the second way here.

Below is the code with the bug.

Second Way)


int main()
{
int *t;
*t=2;
func(t);
printf("%d",*t);
}


void func(int *t)
{
t = (int *) malloc(sizeof(int));
*t=4;
}

Lets start with smallest code and we will be adding one line after another

Code Sample 1)

#include<stdio.h>

int main()
{
    int *t=2;
    printf("%d",*t);
}

Now ideally this code should give run time error, since we have not malloced T and assigned value to it.  But on GCC no error is coming currently and on VS error comes. 

It is how compiler are written, but SAFE PRACTICE is to malloc it.

Code Sample 2)

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

int main()
{
    int *t=(int *)malloc(sizeof(int));
    *t=2;
    printf("%d",*t);
    printf("%p",t);    // This will P address
}

This was GCC output

0xa04b008  2

Code Sample 3)

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

int main()
{
    int *t=(int *)malloc(sizeof(int));
    *t=2;
    printf("%d",*t);
    printf("%p",t);    // This will P address

func(t);

 printf("%d",*t);
    printf("%p",t);    // This will P address

}

void func(int *y)
{
 printf("%d",*y);
    printf("%p",y);  
*y=20;
}

Now many compilers , GCC is one of it throws warning/error  since func()  body is below main function and compiler cannot see it when it encounters func() call inside main. 

Now we can add func() definition in start of main. 

But I more thing which I learned is all you can make warnings into errors in GCC. Bu using     -Werror option. 

> gcc -Werror -o output memory.c    

and all warnings will be converted to errors, so that you don't overlook them.

This is post with more options : https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Warning-Options.html

The output was 

2 0xa04b008 
2 0xa04b008 
20 0xa04b008 

So address location is same inside func and main.

Code Sample 4)

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


void func(int *y)
{
y=(int *)malloc(sizeof(int));
*y=20;
 printf("%d ",*y);
    printf("%p \n",y);  

}

int main()
{
    int *t=(int *)malloc(sizeof(int));
    *t=2;
    printf("%d ",*t);
    printf("%p \n",t);    // This will P address

func(t);

 printf("%d ",*t);
 printf("%p \n",t);    // This will P address

}

Here the output was

2 0xa04b008 
20 0xa04b018 
2 0xa04b008

Here we see that inside the address and value is different, but after that also in main the new value is not retain.

This is because,  int *y , here Y is pointer and is LOCAL. when we called func(t). It passed the value of t address to Y.  But when we malloc y, its address got changed. NOW HERE WE HAVE TO NOTE THAT CHANGING Y ADDRESS WILL NOT CHANGE T ADDRESS, but if we have not malloced Y, then changing its value changes T value, since both point to same address.

Hence once func()  is exist, T retained its address value and the value at it is still 2. 

So this pops a Q. What if we want to create a code in which process 2 malloc address and passed to process1.  Process1 is caller of Process2.

Then we have to use double pointer.

Code)

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


void func(int **y)
{
  *y=(int *)malloc(sizeof(int));
    printf("%p ",*y);
    printf("%p \n",y); 
}

int main()
{
    int **t =(int **)malloc(sizeof(int*));
    printf("%p ",*t);
    printf("%p \n",t); 

func(t);

 printf("%p ",*t);
 printf("%p \n",t);    // This will P address

}

Output is 

(nil) 0xa04b008 
0xa04b018 0xa04b008 
0xa04b018 0xa04b008 

As we can see , since we have malloced, only Y in main, it has some address and *y is NIL. 
then when we malloc *y , it has some address and on returning back to main function same is retained, since we have NOT CHANGES Y address, but address Y points to. 

We have not malloced Y in func, since that would have changed the Y address and no Change in T would have happened. 

Now coming back to our problem, HOW can we pass a function pointer to process2 and its return the correct function the pointer should point to.

Code Sample 1)

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

typedef void(*fp)(int,int);

void add(int a,int b)
{
  printf("%d",a+b);
}

void func(fp y)
{
  y=add;
  y(8,9);
}
int main()
{
    fp f1;
    func(f1);
    f1(2,3);
}


Will this code work. No COMPILE ERROR, BUT RUN TIME ERROR:SEGMENTATION FAULT.
Since like previous code,  when func() is exist and we return back to main, f1 is not pointing to add function.

Here again we have to write code which passes pointer to function pointer and then change the function value.

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

typedef void(*fp)(int,int);

void add(int a,int b)
{
  printf("%d",a+b);
}

void func(fp* y)
{
  *y=add;
  (*y)(8,9);
}
int main()
{
    fp* f1 = (fp*)malloc(sizeof(fp)) ;
    func(f1);

    (*f1)(2,3);
}

This ends our discussion on pointers

Thursday, October 1, 2015

C language : Pointers -1


Everyone knows about pointer. So we are basically going straight into examples are cross checking our knowledge.



int *p;   or int* p;



Which one is better ? The first one for me, as it makes it easy for getting to know whether its int or function pointer.




Now see below

int *func();  int* func(); int (*func)();



here 1 and 2 are same , since C precedence for * is from left to right. hence we have to use brackets when defining function pointer.



So its better to associate * with either data type or function depending on what you are creating, it will help readability of code.




Now see the below code and see if it has any error and try to correct it.




int main()
{

chat **t=func();

printf("%c",*t[3]);
}

char **func()
{

char **p = (char **) malloc(sizeof(char *));
char *t = "icecream";

p = &t;

}





Now see the below code and see if it has any error and try to correct it.

int **func();

int main()
{

int **t=func();

printf("%d",**t);
}

int **func()
{

int **p = (int **) malloc(sizeof(int *));
int *t;
*t = 3;

*p = t;


}





Now see the below code and see if it has any error and try to correct it.

1)

typedef struct point_T{
int **a;
int b;
}point;



int main()
{

point *var;

var = (point *) malloc(sizeof(point));

(*var).b =2;
*var.b=2;        // WHY IS THIS WRONG
var->b=2;

printf("%d",var->b);

}






2)

typedef struct point_T{
int **a;
int b;
}point;



int main()
{

point *var;

var = (point *) malloc(sizeof(point));
       
  // WHICH ONE IS CORRECT : COMPILE WISE   , and WHY THIS PROGRAM GIVE RUNTIME ERROR

**(var->a)=3;
var->**a=3;
(var)->**a=3;
var->(**a)=3;

printf("%d",var->b);
}






3)

typedef struct point_T{
int **a;
int b;
}point;



int main()
{

point *var;
int b=9;
var = (point *) malloc(sizeof(point));
(*var).b =2;
(var->a)=(int **) malloc(sizeof(int *));
**(var->a)=b;     // IS THIS CORRECT  ???

printf("%d",var->b);
printf("%d",**(var->a));
}





4)  The below program is CORRECT

typedef struct point_T{
int **a;
int b;
}point;



int main()
{

point *var;
int b=9;
var = (point *) malloc(sizeof(point));
(*var).b =2;
(var->a)=(int **) malloc(sizeof(int *));
*(var->a)=&b;

printf("%d",var->b);
printf("%d",**(var->a));
}





If you run the above programs, you will see that  when dealing with pointers.

1) If they are not string literals, then  each  pointer has to be malloced, if you want to store some value in it , else segmentation fault.

2) if it is string literal, then by default malloc gets done.

3) if you are just using pointer to point to some address, no need to malloc, BUT IF IT IS DOUBLE POINTER, then INSIDE POINTER has to be malloced.






One last program for struct and pointers.




typedef struct point_T{
int **a;
int b;
}point;



int main()
{

point var;
int b=9;

var.b =2;
**(var.a)=b;  // Will this work, if not how will u correct it

printf("%d",var.b);
printf("%d",**(var.a));
}





Now coming on the  VOID POINTERS.


Lets see why we need them


Scenario 1 )


There are two processes, each one having their own structure or enum. Now when we want to pass some enum or struct to other process, how we will pass it.


Ex:


in process 1  we have  enum  week1  and in process we have enum week2. now process1 calls func()  to pass value to process2.


What will be the function definition


if we use


void func(week2 var1)  // then we get compile error , since week2 enum if not visible to process1.


if we use  func(week var1)  and then in process2 we get a compile error since week is not visible in process 2.


Hence we have to use void pointer, and take care of assigning correct values in each process.


Some things to take care


1) VOID POINTER can't be deference


Ex  :


int main()
{


int *t = (int *)malloc(sizeof(int));
*t=10;


void *y;


*y =10;  // This will give error
y= t;  // This is correct way.


printf("%d",*y) // again will give error


printf("%d",*((int *)y));  // This is correct way
}


As we can see everytime we have to dereference a void pointer, we have to cast it to some DATA TYPE pointer.




Scenario 2)


Function pointer and Void pointer.


Void pointer , you can think as something which provides a limited level of abstraction to C language.


Its a bucket, in which we can put any type of pointer, Only when we are emptying the bucket we should know what was in it actually.


So when we use function pointer and void pointer.  Again most of them are used when we have more than one process.  In that case


1) Sometimes we don't know what type of function needs to be called.


Example : Suppose there are two friends, One writing code for processing details of employee salary depending on it post.


the other friend is writing code of storing employee details and passing it to other friend.


Now if Friend1 has not told or due  to visibility the function name is not known, then we can't call any function.  So in that case we just call a function pointer, and also pass some data to friend2 so in know emp type.


And will call respective function in his code.




Some points to take care when defining Function Pointers are


1) The correct declaration is


return type (*func_pointer_name) (parameters);


2) Also its best practice to typedef this so that it will become easier


typedef   return_type (*typedef_name)(parameters) ;


Yes syntax is almost same, only we have to add typedef in starting.


3) Unlike data types, function name is itself a pointer or address.


for int we have to do like below


int r=8;
int *t;
t=&r;  // Here we are assigning the address


but with function pointers


void func1(int,int);
void (*func_pointer)(int,int);
func_pointer = func1;          //  No & sign was used.


which seems like below declaration


void func_pointer(int,int);


Only thing is here func_pointer is static and can't be used to change function call.


Now when u have typedef


void func1(int,int);
typedef void (*func_pointer)(int,int);


func_pointer f1;


f1=func;


4)  How to dereference a func pointer.


It can become a little tricky when dereferencing a function pointer, since like int,char pointer our tendency can be to use * while dereferencing, but we have to remember that * only means that it is function pointer, apart from that we have to treat it like normal function name.




int func1(int,int);
int (*func_pointer)(int,int);
func_pointer = func1;          //  No & sign was used.




Now here if we want to print return value of  func1, we would have done like below


printf("%d",func1(2,3));


Now if func_pointer is used, even then we will do the same


printf("%d",func_pointer(7,8));


No need to use * while deferencing.




5) How to pass function pointer.


Now with data type we can use pointer in two ways, while passing pointer from function1 to function2  we assign value in function1  or  we can assign value in function2.


First Way)


int main()
{


int *t= (int *) malloc(sizeof(int));
*t=2;
func(t);
}


void func(int *t)
{
int h=*t;
}


With function


typedef  int (*fp)(int,int);


int add(int a ,int b)
{
 printf("%d",a+b);
}


int main()
{
fp f1 = add;
func( f1)
}


void func(fp t)
{
  t(2,3);
}


Now can we use   typedef int (fp) (int,int).
Yes we can , but it is not used much, since whenever u will pass a function, you have to pass function pointer.


typedef int(fp)(int,int);


int add(int,int);


int main()
{
fp t;
t=add;  This will result in compile error, we have to use  


fp *t;  then only it will work, so its better to have * in typedef only.
}




Second Way)




int main()
{
int *t;
*t=2;
func(t);
printf("%d",*t);
}


void func(int *t)
{
t = (int *) malloc(sizeof(int));
*t=4;
}




With function




typedef  int (*fp)(int,int);


int add(int a ,int b)
{
 printf("%d",a+b);
}


int main()
{
fp f1;
func( f1)
f1(2,3);
}


void func(fp t)
{
t=add;
}


We will carry the discussion of 2nd approach in second post.















Sunday, September 27, 2015

C language : malloc free realloc and memory

Run this below program

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



int main()
{

int *p=malloc(sizeof(int)*7);
printf("%d ",p);

free(p);
printf("%d  ",p[2]);


int *m=calloc(8,sizeof(int));
m[2]=100;
printf("%d ",m);
printf("%d  ",m[2]);
m[6]=90;
printf("%d  ",m[6]);

free(m);
realloc(m,4);
printf("%d ",m);
printf("%d  ",m[2]);
printf("%d  ",m[6]);
free(m);

}

First of all it will tell

1) syntax of free, malloc, realloc,calloc

2) If you pay attention we can see even after freeing  p , we can still access p[2].

The reason being " when we malloc or calloc some memory" compiler stores some additional information regarding that memory...size , initial values" , and it returns back actual RAM address.

When free is called, all it does is removing that information.  Then again depending on compiler free can set the pointer to NULL, can all delete the value stored in that RAM address.

But it seems GCC doesn't does that, therefore since we have address of physical address we can still access what is in it.   Therefore  whenever you call free in your code, REMEMBER to MAKE pointer NULL after that, else memory corruption can happen.


This also answers the question which is asked many times in interview , that how does FREE knows how much memory to free , when we don't pass any size to that.


Also the below code will give run-time error. Since with first free we have deleted any information regarding the pointer M. hence at second free compiler returns error.


int main()
{

int *M=(int *)malloc(sizeof(int));
free(M);
free(M);
}

C language : Memory Layout


Now since we have seen extern,static,local variable and also string. So the next important thing comes is Memory Layout.

Now I myself is studying at the same time and I have lots of doubts . Some get cleared over net and some I just assume to be true or false, until proved otherwise. :)

Most of us knows that C memory layout is basically

Stack, Heap,BSS,Code segment.   But we will here try to see how much we can get . The first thing I will be doing is to mention the various link i have gone through and after that what I understood from these.


http://www.geeksforgeeks.org/memory-layout-of-c-program/
http://cs-fundamentals.com/c-programming/memory-layout-of-c-program-code-data-segments.php
https://www.cs.cmu.edu/~guna/15-123S11/Lectures/Lecture06.pdf
http://www.tenouk.com/ModuleW.html


Now simply put,

Every machine which runs code has Opearting System, RAM , and then our C programs.

Taking GCC into perspective,

The stages of writing and running a program involves.

Using example of below program

#include<stdio.h>

#define CHETAN 12

int main()
{
 printf("%d",CHETAN);
}

1) the best command I got over net to generate all types of file during various stage is

> gcc -o memory memory.c  --save-temps

This will generate

1)  Preprocessor  Stage  :  memory.C  to memory.I  file  Preprocessed code is generated
2)  Compiler Stage   :  memory.I file to memory.S  file   Assemble Code is generated
3)  Assembler Stage  :  memory.S file to memory.O file  Object Code is generated
4)  Linker Stage  :  memory.O file to ELF file                  Executable Code is generated.


Now interested people can workout and see different types of files. All files except ELF and object can be opened with any text editor.

To see Object file code , you can use

> objdump -d memory.o


So we have seen the stages and various code file generated . Now what happens when you run the executable.

The LOADER loads the program into RAM/ primary memory, which creates PROCESS ADDRESS SPACE, since every program we run is a process.


Now every process/ C program can have below types of  variables.

initialized global variable : DATA
uninitialized global variable : BSS
initialized static global variable :  DATA
uninitialized static global variable:    BSS
static local variable ( it should be always initialized):  DATA
static local variable ( in case it is uninitialized):             BSS

local variables:  STACK
malloc space:    HEAP

string literal : ( like char *p="asasasas")  :  READ ONLY DATA    
constant    : READ ONLY DATA


Note  the pointer which points to MALLOC space , there storage location will depend on where that pointer is define.


And finally the object file code which was generated :   TEXT

In case of ELF file, the various section are

ELF file section

.bss        BSS
.text       TEXT
.rodata   READ ONLY DATA

the other gcc command which can be used

> readelf -a memory.o


So this was about ELF section,  STILL I am not sure where local variables and malloc gets stored.


Now about PROCESS ADDRESS SPACE.

It has following sections.

Starting from LOWER ADRESS OF MEMORY.

TEXT : This portion of a process contains the instruction code.  Some OS can share this section between two process running the same code. it is READ ONLY SECTION

DATA segment :  It has  DATA as defined above. Each process has its own set, no SHARING.
 IT is further divided into two parts .

            READ ONLY : global constants , string literals.   char *s="Hello";
            READ WRITE : global and static variables which are not constant. Also  char s[]="hello";

Now if you remember previous post about string, you know the difference between char*s and char s[].

BSS segment : It has BSS as defined above. NO SHARING.

HEAP segment : HEAP.

STACK segement : STACK.


One more thing,  I was wondering where does constant uninitialized variables are stored, On further searching on net I find out that it depends on your compiler.

So  all constant can be saved in text section.  or depending on whether they are global or local and initialized or uninitialized , they can also be stored in thier respective section , i.e BSS,DATA,STACK  since each of these section can have write protected region in them.




So now we know  the stages of C program and how it is stored in RAM.  Further we will see some code and try to find out memory of each section.

we can use SIZE command in ubuntu to check for memory size.

We will be using below program and then add more variables.

int main()
{
}


Now with this program , when I run size I get

text      data   bss   dec     hex    // there is no stack or heap section shown.  The values were
1033    276    4      1313   521

Leave the text part,  I am not sure why   data and bss  has some values even though we have not defined any type of variables.

Lets assume that to be some kind of overhead, in lieu of better explanation.

Now we add a local variable

int main()
{

int a;
}

Now i have  added some local variable, first not assigned any value  there was no change , then when i assigned them value  size of  dec and hex got changes.

You can check more from your side.

Now adding one global int variable, uninitialized   bss size got increased by 4.

Adding uninitialized   static variables,  bss size increased by 4.

Initializing those variables, make data size increase by 4, and bss gets decreased by 4.

Having extern int a;  doesn't increase size since no memory was saved, extern simply tell compiler that this variable is saved somewhere else.



If suppose for  below program the size is like

int main()
{

int a;
}

data   bss
20       4

then what will be size for below program


int main()
{

int a;

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

scanf("%d",&a);

}

it will be

data   bss
28       4

the increase of size of  data is nothing to do with  int *p.....but it seems every function call we made,

that function pointer gets saved in data ...since we have malloc()  and scanf()  size increased by 4*2.


if we add a printf , data size will increase further by 4 bytes.

It seems local function call doesn't increase size , even in local function we are doing malloc.

but if in local function we define static variable, that is stored in DATA segment.



Thursday, September 24, 2015

C language : String


Recently I was working on some string related programs.  I came across some error, when I asked my friend he also faced the same issue.

Even though it is very trivial, I came to know since we were away from some basics for long time, we faced this issue.


In C we don't have string type. So we basically use either


char *cb="name";
char c[5]="name";

Now the difference between two are  cb is pointer to char array.  and c is itself a array which has "name" stored in it.

More deeeply,

when we do *cb="name";

In C memory layout --->data segment--->initialized data segment  "name" is stored and  cb is stored either in heap,stack,data segment  depending on local,static,extern variable.

And it stored value of "name".  Also the address where name is stored is READ ONLY.

So you cannot do cb[2]='g';

Now using cb, we can perform strcmp function or other function which will use the string stored at cb pointer.

But if we want to do strcpy , then error will be thrown. Simply because we haven't MALLOCed anything.

So what about the below functions. Working below two functions will tell more difference 


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


int main()
{

char *t;

t= (char *)malloc(sizeof(char)*7);
t="chetan";
printf("%s",t);
strcpy(t,"rathore");
printf("%s",t);
}

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

int main()
{

char *t;

t= (char *)malloc(sizeof(char)*7);
strcpy(t,"rathore");
printf("%s",t);

t="chetan";
printf("%s",t);
return 0;
}

The below program will further give some insight

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

int main()
{

char *t;

t= (char *)malloc(sizeof(char)*7);
strcpy(t,"rathore");
printf("%s",t);

t="chetan";
printf("%s",t);
free(t);
return 0;
}

Now when we use

char cb[5]="name";

here cb is allocated space in heap or stack depending on local,static,extern.

so we can perform cb[3]="k"

also all strcmp and strcpy will work.  But what will not work here is

cb=NULL, since cb is not pointer.
cb='\0'; since cb is not pointer

BOTH WILL GIVE COMPILE TIME ERROR

Also strcpy(cb,NULL)  or strcpy(cb,'\0')  will give RUNTIME ERROR

Please pay attention to COMPILE ERROR and RUNTIME and LINK TIME ERROR.


Below program will tell difference between pointer of any type and array of same type.

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

int main()
{
int t[4];
int *a;
t=&a;

}


At the closing stages , some more points .

In case you have defined array char

char strin[6];

then to make string empty , we can use  strcpy(strin,"");

but in case we have char pointer , we could have used

char *strin;

strin=NULL;  or strin='\0';




C language : Static and Extern



Some of points regarding static and extern.

1) By default , global variables are extern

2) Local variables are neither extern or static by default.

3) Defining a local variables as extern, doesn't have any effect.
3.1) defining local variables as extern and assigning value to it results in COMPILE ERROR.

So never have local variables as extern.

4) Local variables as static saves its value between function calls.

Also it is better to have value assigned to static value at time of definition.

5) Define global variable as STATIC only if you want that variable scope as limited to that file.


Both STATIC and EXTERN variable are saved either in BSS if uninitialized and in DATA if initialized.



Regarding to function, compiler treat them as implicitly EXTERN. therefore we don't need to add extern in front of function.

But if you need to limit the scope of function to some one file, then static can be added in front of function.

But then LINK ERROR will come if you are trying to access this function from some other file.

STATIC with function name is mostly used if you have 2 definition of same function, then you can limit the scope of one function by using STATIC.

Monday, September 21, 2015

C Language : Static


So in the last post , we have seen the EXTERN.  In this post we will see STATIC .

We can define STATIC in global variables or local variables.

If we define STATIC in global variables, then the global variables scope will be that file only.
So even if you have extern that variable in some other file , then error will come.

Program 1)

static1.c

#include<stdio.h>

static int a=10;

int main()
{
func()
}

static2.c

extern int a;

void func()
{
printf("%d",a);
}

now if you GCC and compile both files separately then , there will be no COMPILE ERROR.
But on creating object file, LINK ERROR will come. Since a is not visible outside the static1.c

Program 2)

static1.c

#include<stdio.h>

static int a;
a=10;

int main()
{
func()
}

This will give COMPILE ERROR, since non static definition cannot follow the static definition.



Now lets see what happens when static is defined with local variable.

Program 3)

static1.c


#include<stdio.h>

int main()
{

func();
func();
}

int func()
{
static int a;
a=10;
a++;
printf("%d",a);
}

the output of the function will be 11 and 11

Since static variable are assigned value at time of declaration. If we assign value after declaration, then everytime func is called , that value will be put in the function.

Program 4)

static1.c


#include<stdio.h>

int main()
{

func();
func();
}

int func()
{
static int a=10;
a++;
printf("%d",a);
}

this will behave as it should be , output will be 11 and 12.

What will happen if static variable is not initialized.

All static and extern variables will be initialized to zero if not explicitly assigned some value.

Sunday, September 20, 2015

C Language : Extern


I marvel at the way we humans are designed or made. We simply can't remember things which we are not in contact with for a certain period of time .

Its like either our memory gets rewritten by new memories or the way of accessing our old memories is not good enough.

I am pretty sure , I would have read about EXTERN a lot of times, but not using it on daily basis and suddenly again we have to go to some book, to check the usage.

Then the second thing is curiosity. I know a certain way of using EXTERN, but then a sudden urge will come to see what if  I have defined it in some other way or some other place and etc etc .

Now One more time and quite possibly not the last time , here again I go about EXTERN.


All the below program snippet use GCC on Ubuntu

To best see how extern works,  compile each .C file separately and  then make executable

Program 1)

extern.c file

#include<stdio.h>
int a=10;

int main()
{
    printf("%d",a);
  func();
}

extern2.c

int a=20;

int func()
{
printf("%d",a);
}

Compile both programs
gcc -c extern.c
gcc -c extern2.c

two object files will be generated  extern.o  and extern2.o

Try to generate executable
gcc -o output extern.o extern2.o

You wll get LINKING ERROR , saying multiple defination of a

Program 2)

Now remove the int a=20;  line in extern2.c  and try again

This time you will see , COMPILE ERROR for extern2.c , since a is undefined.

Program 3)

In extern2.c , add    extern int a;  at the start

  This will work and no error will come , since

1) having extern , tells compiler to check for a at run time .
2) At run time , only one declaration of a is present in extern.c

Program 4)

What if you add  extern int a=2; either in extern.c or extern2.c

There will be no compile error, but extern will not work,  it will be simply as you have defined
int a=2;



What about local variable defined as extern ?

This will not have any effect.
1) If you initialize value at same time as declaring then COMPILE ERROR will come.

else

it will simply treat a as global variable, note that a should be declare as global variable in some file.

ex

Program 5)

extern.c

#include<stdio.h>

int main()
{

extern int a=8;          // COMPILE ERROR


Program 6)

extern.c

#include<stdio.h>

int main()
{

extern int b;
printf("%d",b);
}

extern2.c

int b=10;

int func()
{
printf("%d",b);
}

This will work.

Even

extern.c

#include<stdio.h>

int b=10;

int main()
{

extern int b;

printf("%d",b);
}

will work.

Program 7)

extern.c

#include<stdio.h>

int main()
{

extern int b;
printf("%d",b);
}

extern2.c


int func()
{
int b=10;
printf("%d",b);
}

There will be no COMPILE ERROR, but will be LINK ERROR  since there is no global definition of  a.

If you try the above programs, you will pretty much know the working of extern.