Setting NULL to struct pointer, but never NULL when checked

Given, in the function called,

void callFunct1 (arg_t *q) {
   q = NULL;
};
EXPORT_SYMBOL(callFunct1);

returns a null.

Why is the reason that in another function, q is never NULL? How can I correct it?

arg_t qH; 
arg_t* q; 
                                        //
callFunct1 (&qH);
q = &qH;


if (q == NULL) {    
      .....
    }

arg_t is just a struct.

Upvotes: 0

Views: 112

Answers (3)

WhozCraig
WhozCraig

Reputation: 66254

Pointers are no different than any other non-array variable in C. When passed as a parameter, if you want to modify something as in/out, you have to pass by address. Declare the parameter to be a formal pointer-to-the-type and pass the address of the entity from the caller, using the dereference operator * to access the caller's value.

Just as this:

void foo(int *p)
{
    *p = 5;
}

is invoked like this:

int x;
foo(&x); // x will be 5 on return

So it is with pointer-types as well. If you want to modify the pointer by address then the address is precisely what is needed. Declare the parameter as a pointer-to-pointer-to-arg_t and dereference it to set the referenced pointer to NULL:

void foo(arg_t** pp)
{
    *pp = NULL;
}

and

arg_t *p;
foo(&p);  // p will be NULL on return

Upvotes: 3

Lundin
Lundin

Reputation: 215115

That function returns nothing. You pass a pointer to a struct. That pointer is a copy of the passed pointer, it is not the same variable as in main.

This is what goes on between the lines: if we have a caller like the code below

int main()
{
  arg_t some_struct;
  arg_t* some_ptr = &some_struct;

  callFunct1 (some_ptr)
}

then upon calling callFunct1

  • some_ptr points at some_struct.
  • The function parameter arg_t* q is allocated on the stack.
  • The contents of some_ptr is copied into q.
  • Both some_ptr and q now point at some_struct.
  • Then you set q to point to NULL.
  • Then the function ends. q ceases to exist.
  • As you have not changed some_ptr, it still points at some_struct.

Now if you had not set some_ptr to point at anything, it would have contained any garbage value. When making a debug build of your program, variables are likely set to NULL by default, but there are absolutely no guarantees for this!

So if some_ptr was uninitialized and happened to contain the value NULL when you called the function, it might have appeared as if you successfully set it to NULL. But in reality, you were just plain lucky that your uninitialized variable contained that value.


To actually set the variable in main to point at NULL, you would have to do

arg_t callFunct1 (void) {
  return NULL;
};

arg_t* some_ptr;
some_ptr = callFunct1 ();

Upvotes: 0

alk
alk

Reputation: 70981

void callFunct1 (arg_t *q)

returns nothing as its return type is declared void.

Its argument q is a copy of the value passed as parameter when callFunc1 is called, and this copy lives on callFunc1's stack for as long as callFunc1 runs.

So this line

q = NULL;

assigns NULL to the q existing only locally to callFunc1.

Upvotes: 0

Related Questions