0

I write a C program. I have 2 pointers *a and *b. Now, I impose *a = 20 and *b = 10. After that I impose a = b in subroutine but the value seem doesn't change. I expect that *a = 10 and *b = 10. Please help me find a solution for this. Thank you.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void Copy(int *a1, int *a2)
{
    a1 = a2;
}


void Test()
{
    // a = 20
    int *a = (int *)malloc(sizeof(int));
    *a = 20;

    // b = 10
    int *b = (int *)malloc(sizeof(int));
    *b = 10;

    Copy(a, b); // a = b
    printf("\na = %d", *a);
    printf("\nb = %d", *b);
}

int main(int argc, char *argv[]){
    Test();
    fflush(stdin);
    printf("\nPress any key to continue");
    getchar();
    return 0;
}
Dang_Ho
  • 323
  • 3
  • 11
  • If you are working on **C** pointers and memory address, you should start from now on avoid casting the result of malloc. – Badda Jun 07 '17 at 15:25
  • In `a1 = a2;` you copy the argument, not what it points to. – Weather Vane Jun 07 '17 at 15:25
  • https://stackoverflow.com/questions/2229498/passing-by-reference-in-c What's happening is that both pointers are copied when Copy() is called, which doesn't change a or b, but only their copies. – ginginsha Jun 07 '17 at 15:25
  • 1
    The pointers are passed by-value, you only change the local copy of the pointer. If you want to change the value *pointed to*, write `*a1 = *a2` –  Jun 07 '17 at 15:26
  • Note that [using `fflush(stdin)`](http://stackoverflow.com/questions/2979209/using-fflushstdin) is contentious and not portable. – Jonathan Leffler Jun 07 '17 at 15:27
  • Don't forget to free the memory when you are done. `free(a)` in test – Seek Addo Jun 07 '17 at 15:40
  • Can you tell me why @JonathanLeffler?? Can i change `fflush` via another function? – Dang_Ho Jun 07 '17 at 15:45
  • On most platforms, the behaviour of `fflush(stdin)` is undefined, so it may do nothing or anything — and anything includes doing nasty things. Fortunately, such functions seldom actually do nasty things, but they're allowed to crash, etc. What to do? I'd simply drop the line. There isn't any input left over from a previous `scanf()`, so there's no real reason to flush standard input before reading from it. That's also the portable solution. You can use `int c; while ((c = getchar()) != EOF && c != '\n') ;` if you like, but if the user hasn't yet typed anything, that ignores their input. – Jonathan Leffler Jun 07 '17 at 15:53
  • There isn't a portable solution to 'read up to the newline if there is any data waiting on standard input'. There are platform-specific solutions (and `fflush(stdin)` is a platform-specific solution for certain platforms — primarily Windows using the Microsoft runtime libraries). – Jonathan Leffler Jun 07 '17 at 15:54

2 Answers2

1

Function arguments are passed by value. So inside the function Copy you are modifying a copy of the pointer not the original pointer you had in the Test function. So when you leave the Copy function the pointers outside are not modified.

Change the Copy to receive a int **, so you can change inside the value of pointers

void Copy(int **a1, int **a2)
{
    *a1 = *a2;
}

And call the function in this way:

void Test() {
    ...
    Copy (&a, &b);
    ...
}
Jesferman
  • 1,049
  • 7
  • 12
  • 1
    How do you intend to `free` the memory which was allocated to variable `a`? I would say that the comment above from @FelixPalmen is the correct answer. – Weather Vane Jun 07 '17 at 15:38
  • He should store a temp pointer pointing at the same place than `a` before changing its value, to be able to free that memory – Jesferman Jun 07 '17 at 15:42
1

If you want to assign the values, such that after the call of Copy *a == *b holds, then you'd have to change your function as follows:

void Copy(int *a1, int *a2)
{
    *a1 = *a2;
}

If you want to assign the pointers, such that after the call of Copy a==b holds, then you have to pass a pointer to the pointers:

void Copy(int **a1, int **a2)
{
    *a1 = *a2;
}

void Test() {
    ...
    Copy (&a, &b);
    ...
}

Note that a==b also implies that *a == *b.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58