2

I have a function f1 which expects void pointer. From the caller I want to have generic logic of passing void pointer to A which modifies the pointer internally.

sample code is pasted below :

#include "stdio.h"
#include "malloc.h"
void f1(void* a)
{
    printf("f(a) address = %p \n",a);
    a = (void*)(int*)malloc(sizeof(int));

    printf("a address = %p \n",a);
    *(int*)a = 3;

    printf("data = %d\n",*(int*)a);
}

void f(void)
{
    void* a1=NULL;
    printf("a1 address = %p \n",a1);

    f1(a1);

    printf("a1 address = %p \n",a1);
    printf("Data.a1 = %d\n",*(int*)a1);
}

int main()
{
    f();
}

But it causes segmentation fault. Is there any way to make it work without changing prototype of function f1?

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
user3932994
  • 37
  • 1
  • 5
  • 1
    I have seen people casting `void *` to anything like `int *` or `float *` for the return value of `malloc()` but you ... `void *` -> `int *` -> `void *`? Why? – Iharob Al Asimi Jun 26 '15 at 11:14
  • @TheParamagneticCroissant maybe the same reason [this question](http://stackoverflow.com/q/31010895/2173917) got. ....sigh.... :-| – Sourav Ghosh Jun 26 '15 at 11:38

2 Answers2

5

C uses pass-by-value for function argument passing. If you have to change the passed variable itself from inside the function, you need to have a pointer to the variable.

In your case, it should be a pointer to pointer.

Otherwise, after the call to f1(a1);, in f(), a is still NULL and dereferencing it invokes undefined behaviour. Segmentation fault is one of the side effects of UB.

That said,

  1. Please see why not to cast the return value of malloc() and family in C.

  2. you don't need #include "malloc.h" to use malloc(), rather use #include <stdlib.h>. It is declared in stdlib.h header file.

Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

You need to modify the pointer, not the ponted to data. So you must pass a pointer to the pointer, like this

void f1(void **a)
 {
    int *b;
    b = malloc(sizeof(*b));

    printf("b address = %p \n", b);
    if (b != NULL)
     {
        b[0] = 3;
        printf("data = %d\n", *(int *) b);
     }
    *a = b;
 }

The way you do it, the pointer inside f1 is a copy of the passed pointer, they both contain the same initial value NULL, the value you used in f() to initialize a1, but you alter the value of the local pointer only.

You then dereference a1 which is still NULL, and dereferencing a NULL pointer, causes undefined behavior. In your case the behavior is that a segmentation fault happens.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97