2
    # include<stdio.h> 
# include<stdlib.h> 
   
void fun(int *a) 
{ 
    a = (int*)malloc(sizeof(int)); 
} 
   
int main() 
{ 
    int *p; 
    fun(p); 
    *p = 6; 
    printf("%d\n",*p); 
    return(0); 
}

Why is the above code not valid ? And why does it give a segmentation fault?

  • 1
    The (uninitialized) pointer value stored in `p` is passed _by value_ into `fun` where you allocate memory, store it and then `a` is popped off the stack, leaking that memory. You then dereference the original (uninitialized) value `p` and try to store data there, which is Undefined Behavior. – paddy Jul 23 '20 at 07:23
  • 1
    Assigning to a function's (non-reference) argument has no effect outside that function. There is nothing special about pointers. – molbdnilo Jul 23 '20 at 07:24
  • The code is valid, in the sense that it does not contain errors for which the standard requires a diagnostic. It has undefined behaviour though because `fun(p)` does not change `p` (the argument `a` is passed to `fun()` by value, so the assignment to `a` does not affect value of `p` passed by `main()`). `p` is uninitialised, so assigning `*p = 6` gives undefined behaviour - and a compiler is not required to diagnose undefined behaviour. – Peter Jul 23 '20 at 07:30

1 Answers1

1

Because a is passed by-value itself, then any modification on itself in the function has nothing to do with the argument.

You can change it to pass-by-reference as

void fun(int *&a) 
{ 
    a = (int*)malloc(sizeof(int)); 
} 

BTW: In C++ better to use new (and delete), or don't use raw pointers from the beginning.

songyuanyao
  • 163,662
  • 15
  • 289
  • 382