0
    void s(int* a, int* b) {
        a=b;
    }
    int main(int argc, char* argv[]) {
        int* a = malloc(sizeof(int));
        int* b = malloc(sizeof(int));
        int c = 10;
        int d = 5
        a = &c;
        b = &d;
        printf("%d %d\n",*a,*b);
        s(a,b);
        printf("%d %d\n",*a,*b);
    }

I am so very confused. This is very simple code. I thought that this would result in a and b pointing to the same value. When i do a=b inside of the main function everything works as expected. When I use gdb it even shows that they point to the same place in memory and the function is not being optimized away!!! So what is happening? Is the function creating its own local copy? Why don't these point to the same variable please help.

  • 3
    don't think it's mentioned in the answer.. beware you have memory leaks here. Assuming `malloc` succeeds, `a` and `b` both point to chunks of memory. When you reassign those to the addresses of `c` and `d`, you no longer have references to the `malloc`ed memory, and your process will hang on to this indefinitely. Not a big deal here, when the process exits the OS will clean up any memory allocated to it. But in a useful program that runs continuously, memory leaks can bleed your system of memory as they accrue. – yano May 09 '19 at 03:39
  • Looking at the code, I get the feeling that OP thinks `a = &c;` does something different than it actually does. To make it clear: this assignment changes the pointer not the value. If you want to change the value in your allocated memory then you would have to do `*a =c;` – Kami Kaze May 09 '19 at 06:46

2 Answers2

2

You want to change the pointers values. Pointers are passed by value, so you need a pointer to the pointer to change its value:

#include <stdio.h>

void s(int** foo, int** bar)
{
    *foo = *bar;
}

int main(void)
{
    int c = 10;
    int d = 5;

    int *a = &c;
    int *b = &d;

    printf("%d %d\n", *a, *b);  // 10 5

    s(&a, &b);

    printf("%d %d\n", *a, *b);  // 5 5     a points at d as well
}

With your version you only changed the parameters which are copies of the values passed to the function.

To help you better understand, consider this:

#include <stdio.h>

void value(int foo, int bar)
{
    foo = bar;  // changing local copies
}

void pointer(int *foo, int *bar)
{
    *foo = *bar;  // changing the value foo points to to the value bar points to
}

int main(void)
{
    int a = 5;
    int b = 7;

    value(a, b);
    printf("%d, %d\n", a, b);  // 5, 7

    pointer(&a, &b);
    printf("%d, %d\n", a, b);  // 7, 7
}

We did that with the type int. Now lets just replace int with int*:

#include <stdio.h>

void value(int *foo, int *bar)
{
    foo = bar;  // changing local copies
}

void pointer(int **foo, int **bar)
{
    *foo = *bar;  // changing the value foo points to to the value bar points to
}

int main(void)
{
    int x = 5;
    int y = 7;

    int *a = &x;
    int *b = &y;

    value(a, b);
    printf("%d, %d\n", *a, *b);  // 5, 7

    pointer(&a, &b);
    printf("%d, %d\n", *a, *b);  // 7, 7  now both point at y
}

So you see, it's the same concept both times. In the first example the values pointed to are ints and their values are numbers, in the second example the values pointed to are int*s and their values are pointer values (<~ standard terminology, "addresses"). But the mechanism is the same

Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Thank you. Can you please explain what was happening when I was just passing it as a single pointer. Because that method of a=b works when it is in main but not in another function. – please_help_im_confused May 09 '19 at 02:30
  • I'll give you an example in my answer. Please give me a minute or two. – Swordfish May 09 '19 at 02:32
  • Sorry, I didn't see what was written underneath the code. So, if I am correct a new object is created and that object references the same thing the parameter references. That is instead of what I thought which was that you pass the address of the pointer. – please_help_im_confused May 09 '19 at 02:33
  • I added another example to my answer. – Swordfish May 09 '19 at 02:39
-2

You program is almost correct but you need to pass the address of the variables in the function as you using call by refrence and in the function take pointer to pointers.

  • C has no concept of "call by reference". – Swordfish May 09 '19 at 03:25
  • But we need to pass the address of the variable as in the function's argument pointers are there – Ritesh Yadav May 09 '19 at 03:30
  • Yes, you take the address of some variable and pass it to a function that takes a pointer. The address (the pointer value) gets *copied* to the parameter of the function. That is call by value, not call by reference. – Swordfish May 09 '19 at 03:32
  • @Swordfish, I don't get it why you said "C has no concept of call by reference"?, How about this (https://fresh2refresh.com/c-programming/c-function/) reference where it says call by reference? – Iron Fist May 09 '19 at 03:48
  • 1
    They also [use `getch()` in a "Hello World"-program](https://fresh2refresh.com/c-programming/c-basic-program/) that only includes `` ... Better read that: https://stackoverflow.com/a/30519731/3975177 – Swordfish May 09 '19 at 03:55
  • 2
    Look at that: `void foo(int &bar) { bar = 42; } int main() { int x = 5; foo(x); /* x == 42 now */ }`. *That's* call by reference. There is no copying of values. The parameter `bar` is a reference, an alias for the variable passed to the function (here `x`). And in `foo()`s body is also no indirection, no dereferencing of a pointer value. – Swordfish May 09 '19 at 03:58
  • @Swordfish There's no need for that dogma. Passing an address by value = pass by reference, simple as that. Replace the C++ reference syntax with C pointer syntax in your example and you get the very same result, which compiles to the very same machine code. Otherwise we may as well say there is no pass by reference in C++, because the address of `x` in your example is passed by value to the function. Check the disassembly and see for yourself. – Lundin May 09 '19 at 06:28
  • 1
    @Lundin I don't have to look at the assembly. What you say about the machine level is true. But there is a difference on the higher level, a conceptional difference. But I am not here to start a holy war. – Swordfish May 09 '19 at 06:45
  • @Lundin yes the result is the same, but when you change the syntax you change the semantical meaning. The difference between those two methods are quite clear (and maybe dogmatic). And as soon as you start using the pointer without an indirection you can do things not possible in the call by reference case. – Kami Kaze May 09 '19 at 07:10
  • If i give input 09 then on printing this value 9 is only printed why it is so – Ritesh Yadav May 10 '19 at 02:48