12

I am passing a pointer a function that updates it. However when the function returns the pointer it returns to the value it had prior to the function call.

Here is my code:

#include <stdio.h>
#include <stdlib.h>

static void func(char *pSrc) {
    int x;
    for ( x = 0; x < 10; x++ ) {
        *pSrc++;
    }

    printf("Pointer Within Function: %p\n", pSrc  );
}

int main(void) {

    char *pSrc = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";

    printf("Pointer Value Before Function: %p\n", pSrc  );

    func(pSrc);

    printf("Pointer Value After Function: %p\n", pSrc  );

    return EXIT_SUCCESS;
}

Here is the output

Pointer Value Before Function: 0x100403050
Pointer Within Function: 0x10040305a
Pointer Value After Function: 0x100403050

What I was expecting was the value after the function to match the one from within the function.

I tried switching to char **pSrc but that did not have the desired affect.

I am sure the answer is fairly simple, but I am a recovering hardware engineer and can't seem to figure it out :-)

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
asicman
  • 133
  • 1
  • 1
  • 4
  • You need to pass the *address* of your `char *pSrc` so you can modify what `pSrc` points to (keep `char *pSrc`, pass it as `&pSrc`, and have the function take a `char **`. – crashmstr Apr 15 '15 at 19:03

5 Answers5

14

The pointer inside the function is a copy of the passed pointer.

They both hold the same address but have different addresses, so changing the address held by one of them doesn't affect the other.

If you want to increment the pointer inside the function pass it's address instead, like this

static void func(char **pSrc) {
    int x;
    for ( x = 0; x < 10; x++ ) {
        (*pSrc)++;
    }    
    printf("Pointer Within Function: %p\n", pSrc  );
}

and

func(&pSrc);

Also, be careful not to modify the contents, because your pointer points to a string literal, and string literals cannot be modified.

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

C uses pass-by-value for function parameter passing. The value of pSrc is just a copy of the pSrc present in main(), not the same entity as the pSrc from main(). That is why, any changes made to pSrc inside the function func()won't be reflected in main() (caller function).

However, all the changes to *pSrc will sustain.

Solution: To change the pSrc of main() from func(), you need to pass a pointer to pSrc (pointer to a pointer) from main() and adjust the data types accordingly. Also, in that case, please note, the pSrc should be modifiable (present in read-write memory). As it is currently written, the pSrc in main() is not modifiable.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • C also uses pass by reference, does it not? – ryyker Apr 15 '15 at 19:19
  • @ryyker is it so? how, please? Atleast, i my knowledge, it does not. – Sourav Ghosh Apr 15 '15 at 19:20
  • The correct statement I believe would be _With the exception of arrays and functions, C always passes arguments by value_ . ( ***[from here](http://www.maths.cam.ac.uk/undergrad/catam/ccatsl/manual/node50.html)*** , for example ) I understand the point of your answer, and have no real problem with it, only this one point :) – ryyker Apr 15 '15 at 19:22
  • @ryyker I got your point, but I don't agree with your words. In case of arrays also, the _paramater_ itself is passed by value only. Can you change the base address of an array (considering a double pointer) from inside a function? :-) – Sourav Ghosh Apr 15 '15 at 19:24
  • By the same token, are you saying that if I pass a pointer to a struct that the values of the members of that struct are included? They are not, but can be accessed via the _reference_ to location of that struct. Here is ***[another reference](http://courses.washington.edu/css342/zander/css332/passby.html)*** that goes into more detail. – ryyker Apr 15 '15 at 19:29
  • @ryyker absolutely not, please don't get me wrong. I'm not a native English speaker, so my wordings may be confusing. What i try to tell is that the "value at the address" is passed by reference, but the "value" itself (the structure pointer, or the double pointer in our case) is passed by value. – Sourav Ghosh Apr 15 '15 at 19:33
2

When you give a pointer to a function, you have a copy of the reference value that you originally had.

Then, if you modify your pointer, you're modifying a copy.

If you want to update the original one, you need to pass it with a double pointer ** which will let you modify the original pointer, passing a "reference to a reference" (double pointer).

Btc Sources
  • 1,912
  • 2
  • 30
  • 58
1

C is passing parameters by value, so it makes a copy of pSrc inside your function, and all the changes you've made are applied to a copy of pSrc. If you want to change the value of pSrc, then you should pass a pointer to pSrc, like this:

static void func(char **pSrc){ // pointer to char*
     int x;
     for (x = 0; x < 10; x++)
         (*pSrc)++
}
Chan Kha Vu
  • 9,834
  • 6
  • 32
  • 64
1

You call func by passing pSrc. You think you are passing the same variable - That is func will operate on the same memory location when it alters pSrc. This is false.

func gets a copy of pSrc. The stack frame built in calling func will have its own pSrc. What is modified is its version not the calling function's.

To let func operate on the actual variable in main you got to pass address of pSrc - &pSrc.

Relevant concepts - Pass by Value and Pass by Reference.

Prabhu
  • 3,443
  • 15
  • 26