2

In this code, relied on gdb, p changes from 0x602010 to 0x0 when NULL is assigned, (as I would expect)

#include<stdio.h> #include<stdlib.h> int main() { int a = 10; // gdb output int *p = (int *) malloc(sizeof(int)); // p = (int *) 0x602010 p = NULL; // p = (int *) 0x0 p = &a; // p = p = (int *) 0x7fffffffe15c return 0; } 

But, when p is changed outside of main() in task(), I guess it does not change to 0x0 and I don't why:

#include<stdio.h> #include<stdlib.h> void tast(int *p); void task(int *p) { /* before (gdb) p p $1 = (int *) 0x7fffffffe15c (same as variable a) (gdb) p &p $2 = (int **) 0x7fffffffe128 */ p = NULL; /* after (gdb) p p $3 = (int *) 0x7fffffffe15c no change? (gdb) p &p $4 = (int **) 0x7fffffffe128 */ } int main() { int a = 10; // gdb output int *p = (int *) malloc(sizeof(int)); // p = (int *) 0x602010 p = NULL; // p = (int *) 0x0 p = &a; // p = p = (int *) 0x7fffffffe15c // it is possible to change what p points to // after calling task()? task(p); // p will be NULL? return 0; } 

Why p does not change to 0x0 inside task()?

4
  • Was there some code you wanted us to review? Commented Aug 21, 2012 at 20:42
  • 6
    Hint: pointers are passed by value. If you changed an int in task would you expect the change to propagate? You'll need to pass a pointer to a pointer if that's the behavior you want. Commented Aug 22, 2012 at 2:05
  • 1
    If p is not changed inside task() the compiler may have optimized away any changes to the value. Commented Aug 22, 2012 at 3:17
  • c-faq.com/ptrs/passptrinit.html Commented Aug 22, 2012 at 15:51

4 Answers 4

2

A pointer is a value, like an int. Think of it like this: if you passed an int into task() and changed it inside the task function would expect it to change? No, because variables are passed by value.

When you call task you are passing a copy of the value (which, in this case, is a pointer) to the function. What you want to do is change the value of the pointer, which means you need a pointer to the location where the value is stored. This is a pointer to a pointer, int **.

instead:

void task(int **p) { *p = NULL; } 

and

task(&p); 

to pass the location of p *.

Another example, this time using int, which may make it clearer.

void makeTen(int *valuePointer) { // Change the variable that valuePointer is pointing to. *valuePointer = 10; } void demoFunction() { int x = 5; // x == 5 // Call this with a pointer to the variable X. // We are passing the memory address of the variable x. makeTen(&x); // x == 10 } 

If you understand this, change int to be int * and you will understand your original problem.

Sign up to request clarification or add additional context in comments.

Comments

1

In the 1st snippet, you are leaking memory as you assign NULL to a malloc'ed pointer.

In the 2nd snippet, you are passing the pointer by its value. So the changes won't reflect in main. This explains the problem.

Comments

0

If you expect p == NULL in main after passing the pointer, you will need to pass a pointer to the pointer. For instance

void task(int** p) { *p = NULL; } 

and pass

task(&p); 

Also, you should note that this code leaks. You should free(p) before setting p = NULL after the malloc call.

Comments

0

Because you are mistaking the pointer address and the object it points to.

void task(int *p) { p = NULL; } 

This function will take a pointer to int, thus, you are allowed to modify the int value that is stored somewhere else. The address of the variable for your int value is passed by value though. That means, the address is stored locally. Assigning 'NuLL' to a local variable is not what you want.

If you change it to this:

void task(int **p) { *p = NULL; } 

You will take a pointer to a pointer to int. Now the address is also pointed to and you can change it from your code. A pointer to int will have to be passed by reference (which is your case).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.