1

Why segmentation fault occur when I am assigning value to pointer in a function.

source_1.c

int *p = NULL;

func(int **y)
{
    *y = (int *) malloc(sizeof(int));
    *y = 1;
}

int main()
{
    func(&p);
    printf("%d\n",*p);
}    

source_2.c

int *p = NULL;

func(int **y)
{
    *y = (int *) malloc(sizeof(int));
    *y = 1;
}

int main()
{ 
    int *t = p;
    func(&t);
    printf("%d\n",*t);
}        

whats wrong in pointer definition and passing address?

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
sagar
  • 99
  • 1
  • 1
  • 3
  • See this question: [Pointer to pointer clarification](https://stackoverflow.com/questions/21604946/pointer-to-pointer-clarification) – Mark Benningfield Jul 09 '17 at 15:28
  • 2
    `*y = 1;` is assigning a 1 to a pointer. Certainly UB. Did you want `**y = 1`? – chux - Reinstate Monica Jul 09 '17 at 15:28
  • there are a few problems with the posted code. Starting with they are missing the necessary `#include` statements for `stdio.h` and `stdlib.h` – user3629249 Jul 09 '17 at 22:34
  • om C. when calling any of the heap allocation functions (malloc, calloc, realloc) 1) always check (!=NULL) the returned value to assure the operation was successful. 2) the returned type is `void*` so can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. – user3629249 Jul 09 '17 at 22:36
  • this line: `*y = 1;` is overlying the pointer that was just set via the call to `malloc()` with the value 1. I.E. the code now has a memory leak and DE-referencing that pointer will try to read from address 1 (which is not an address owned by the program AND is not properly aligned for a `int` value, Perhaps you meant: `*(*y) = 1;` – user3629249 Jul 09 '17 at 22:38
  • when coding in C, the code must always declare a return type for every function. The signature for `main()` can be `int main( void )` or `int main( int argc, char *argv[] )` note in both the valid signatures that the return type is `int` For the `func()` function, it does not return anything, so the return type should be `void` – user3629249 Jul 09 '17 at 22:44
  • `*y = 1;` is an error, you should see compiler output for this line. – M.M Jul 09 '17 at 23:31
  • When I am printing the value of *y inside the function it is printing '1', but it is good suggestion by whom who have posted about **y @M.M – sagar Jul 10 '17 at 05:15

1 Answers1

2

Simply you can find out whats wrong in your pointer manipulation by using your compiler warnings flags.

In windows and in Visual Studio IDE use built in debugger to see coding faults.

In linux environment on GCC compiler try compile your source code (in my case t.c) with this command

gcc -Wall t.c -o t

gcc produce these warnings

t.c:8:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 func(int **y)
 ^
t.c: In function ‘func’:
t.c:11:8: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
     *y = 1;
        ^
t.c:12:1: warning: control reaches end of non-void function [-Wreturn-type]
 }

This is obvious that assignment *y = 1; is wrong.

Thanks for Mark Benningfield for introduce useful link on using pointer to pointer

make change your code to some like this will solve your problem

#include <stdio.h>


int *p = NULL;

void func(int **y)
{
    *y = malloc(sizeof(int));
    **y = 1;
}


int main()
{

    func(&p);
    printf("%d\n",*p);

}

First for a function that not return any value use void as return type. Second if we try to pass a pointer to pointer to a function as argument for example func(int **y) as y can hold address of a pointer we must call it with func (&p). p is a integer pointer.

At last this is recommended not to cast result of malloc() with somethings like

(int *)malloc(sizeof(int))

cast the result of malloc?

EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
  • The cast is not needed in `*y = (int *) malloc(sizeof(int));`. Recommend `*y = malloc(sizeof(int));`, or even better `*y = malloc(sizeof **y);` – chux - Reinstate Monica Jul 09 '17 at 17:59
  • Can you please explain what is deference between them? or just introduce a link about them? – EsmaeelE Jul 09 '17 at 18:06
  • I just copy paste sagar codes in my answer. but i think as malloc() returns a void * its better to cast it. Also this reference not cast it in exanmples. http://en.cppreference.com/w/c/memory/malloc – EsmaeelE Jul 09 '17 at 18:11
  • See https://stackoverflow.com/q/605845/2410359 Your en.cppreference.com reference is for C++, not C, like this post. – chux - Reinstate Monica Jul 09 '17 at 19:52
  • @chux my link http://en.cppreference.com/w/c/memory/malloc is about malloc in C language although domain name is CPP. consider address of link c/memory/malloc and using stdlib in example that only use in C source code if it is C++ cstdio must be used. thanks for consider my post and give a good link about casting pointers that i am not very proficient on it. – EsmaeelE Jul 09 '17 at 19:59
  • True that link is to C language reference. – chux - Reinstate Monica Jul 09 '17 at 20:01