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

No comments:

Post a Comment