void pointer as argument

42,049

Solution 1

As this is C, you cannot pass the pointer by reference without passing in a pointer to the pointer (e.g., void ** rather than void * to point to the pointer). You need to return the new pointer. What is happening:

f(a1);

Pushes the value of the pointer (NULL) as the stack parameter value for a. a picks up this value, and then reassigns itself a new value (the malloced address). As it was passed by value, nothing changes for a1.

If this were C++, you could achieve what you want by passing the pointer by reference:

void f(void *&a);

Solution 2

Passing a pointer to a1 to your function, you can't change where a1 points. The pointer is passed by value, so in f1 you're only changing a copy of the address held by a. If you want to change the pointer, i.e. allocate new memory for the pointer passed in, then you'll need to pass a pointer to a pointer:

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

Solution 3

To change a variable via a function call, the function needs to have reference semantics with respect to the argument. C doesn't have native reference variables, but can implement reference semantics by means of taking addresses and passing pointers.

Generally:

void mutate_thing(Thing * x)    // callee accepts pointer
{
    *x = stuff;                 // callee derefences ("*")
}

int main()
{
    Thing y;
    mutate_thing(&y);           // caller takes address-of ("&")
}

In your case, the Thing is void *:

void f(void ** pv)
{
    *pv = malloc(12);   // or whatever
}

int main()
{
     void * a1;
     f(&a1);
}

Solution 4

Based on Kerrek SB's example I came with this to demonstrate void pointer-to-pointer as an argument and how it may be used.

#include <stdio.h>

void test(void ** jeez)
{
  *jeez = (void *) (int) 3;
}


int main (int argc, char* argv[])
{
void *a;
test(&a);

int b = *(int *)&a;
printf("value returned = %d\n", b);

return 0;
}
Share:
42,049
Will
Author by

Will

Updated on July 09, 2022

Comments

  • Will
    Will almost 2 years

    The following C snippet:

    [...] 
    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);
    }
    [...]
    

    results in

    a1 address = (nil) 
    f(a) address = (nil) 
    a address = 0xb3f010 
    data = 3
    a1 address = (nil) 
    Segmentation fault (core dumped)
    

    Why doesn't a1 keep the address that has been assigned to it in the function?

  • chris
    chris over 11 years
    In C, you can do that with void f(void **a).
  • pickypg
    pickypg over 11 years
    @chris Good point. Brain fart moment.