Doubt about pass pointer to int.

Discussion in 'C Programming' started by CViniciusM, Feb 29, 2004.

  1. CViniciusM

    CViniciusM Guest

    Hello,

    The output of the code below is:
    number = 10
    number = 0 (or other number except 15)

    Why the output of the second 'number' is not 15? Why the 'number' address is
    not changed?

    Thanks in advance, Vinicius.


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

    void change_int(int *num);

    int main(void)
    {
    int *number;

    number = (int *) malloc(sizeof(int));
    *number = 10;
    printf("number = %d\n", *number);
    change_int(number);
    printf("number = %d\n", *number);

    free(number);
    system("PAUSE");
    return 0;
    }

    void change_int(int *num)
    {
    int *temp;

    temp = num;
    num = (int *) malloc(sizeof(int));
    *num = 15;
    free(temp);
    }
     
    CViniciusM, Feb 29, 2004
    #1
    1. Advertisements

  2. CViniciusM

    fix Guest

    CViniciusM wrote:

    > Hello,
    >
    > The output of the code below is:
    > number = 10
    > number = 0 (or other number except 15)
    >
    > Why the output of the second 'number' is not 15? Why the 'number' address is
    > not changed?
    >
    > Thanks in advance, Vinicius.
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > void change_int(int *num);
    >
    > int main(void)
    > {
    > int *number;
    >
    > number = (int *) malloc(sizeof(int));
    > *number = 10;
    > printf("number = %d\n", *number);
    > change_int(number);
    > printf("number = %d\n", *number);
    >
    > free(number);
    > system("PAUSE");
    > return 0;
    > }
    >
    > void change_int(int *num)
    > {
    > int *temp;
    >
    > temp = num;
    > num = (int *) malloc(sizeof(int));
    > *num = 15;
    > free(temp);


    Just a newbie to C, but I guess this line is the problem.
    temp and num is pointing to the same allocated memory,
    you free temp means you free num,
    and then num is now pointing to some unknown stuffs.

    > }
     
    fix, Feb 29, 2004
    #2
    1. Advertisements

  3. CViniciusM

    Artie Gold Guest

    CViniciusM wrote:
    > Hello,
    >
    > The output of the code below is:
    > number = 10
    > number = 0 (or other number except 15)
    >
    > Why the output of the second 'number' is not 15? Why the 'number' address is
    > not changed?


    Well, since you've invoked undefined behavior in your code, *anything*
    could have happened. See below.

    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > void change_int(int *num);
    >
    > int main(void)
    > {
    > int *number;
    >
    > number = (int *) malloc(sizeof(int));

    Better:
    number = malloc(sizeof *number);
    if (number == NULL) {
    puts("Allocation of `number' failed.");
    exit(EXIT_FAILURE);
    }
    > *number = 10;
    > printf("number = %d\n", *number);
    > change_int(number);

    Remember, the value of `number', a pointer to int, is passed to the
    function change_int().

    First see the comments in the function change_int() below, then come
    back here.
    > printf("number = %d\n", *number);


    OK, you're back. ;-)

    Whoops. `number' no longer points to valid memory, as it has been freed
    in change_int(). You have now invoked undefined behavior.
    >
    > free(number);

    Double whoops. You've now freed the same memory twice. UB again!
    > system("PAUSE");
    > return 0;
    > }
    >
    > void change_int(int *num)
    > {
    > int *temp;
    >
    > temp = num;

    `temp' now points to the same int as `number' in main().
    > num = (int *) malloc(sizeof(int));

    Better:
    num = malloc( sizeof *num);
    if (num == NULL) {
    puts("allocation of `num' in `change_int' failed");
    exit(EXIT_FAILURE);
    }
    > *num = 15;

    `num' now points to memory containing the int 15.
    > free(temp);

    The memory originally allocated to `number' in main() is freed.
    *And*, since `num' now goes out of scope, the memory allocated to it can
    no longer be referenced. MEMORY LEAK!
    > }


    Remember, in C, parameters are /passed by value/. If you want to side
    effect a parameter, you need to pass a pointer to it.

    HTH,
    --ag


    --
    Artie Gold -- Austin, Texas

    "Yeah. It's an urban legend. But it's a *great* urban legend!"
     
    Artie Gold, Feb 29, 2004
    #3
  4. CViniciusM

    Leor Zolman Guest

    On 29 Feb 2004 14:04:49 -0800, (CViniciusM) wrote:

    >Hello,
    >
    >The output of the code below is:
    >number = 10
    >number = 0 (or other number except 15)
    >
    >Why the output of the second 'number' is not 15? Why the 'number' address is
    >not changed?
    >
    >Thanks in advance, Vinicius.


    When dealing with dynamic memory allocation, keep in mind that each call to
    malloc() should be balanced by exactly one call to free(), passing free()
    the value obtained from the malloc() call. With that in mind...

    >
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >void change_int(int *num);
    >
    >int main(void)
    >{
    > int *number;
    >
    > number = (int *) malloc(sizeof(int));
    > *number = 10;
    > printf("number = %d\n", *number);
    > change_int(number);
    > printf("number = %d\n", *number);
    >


    > free(number);


    This should either be the first time the value in number is being passed to
    free() (it isn't), or the first time you've made an attempt to free
    whatever dynamically-allocated pointer is currently in number (that isn't
    the case, either.)

    > system("PAUSE");
    > return 0;
    >}
    >
    >void change_int(int *num)
    >{
    > int *temp;
    >
    > temp = num;


    At this point both temp /and/ num point to the int you're presumably trying
    to change...

    > num = (int *) malloc(sizeof(int));


    But now you have overwritten the address of that int in num with the
    address of a new, dynamically allocated piece of memory. BTW, don't bother
    to cast, it isn't necesesary in C:

    num = malloc(sizeof(int));

    > *num = 15;


    You are now setting the value of the dynamically allocated int you just
    obtained in the previous statement.

    > free(temp);


    You've just freed the dynamic memory that you allocated in main() (pointed
    to by "number" there), and on top of that, the memory pointed to by "num"
    has just been leaked (you've lost that pointer, never to be regained)

    >}


    So, think about all that and give it another shot...
    Good luck,
    -leor


    Leor Zolman
    BD Software

    www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
    C++ users: Download BD Software's free STL Error Message
    Decryptor at www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, Feb 29, 2004
    #4
  5. CViniciusM wrote:

    > Hello,
    >
    > The output of the code below is:
    > number = 10
    > number = 0 (or other number except 15)
    >
    > Why the output of the second 'number' is not 15? Why the 'number' address
    > is not changed?
    >
    > Thanks in advance, Vinicius.
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > void change_int(int *num);
    >
    > int main(void)
    > {
    > int *number;
    >
    > number = (int *) malloc(sizeof(int));


    The cast is unnecessary.

    Check that malloc succeeded before relying on its return value for storage
    purposes. (If it failed, it will return NULL.)

    > *number = 10;
    > printf("number = %d\n", *number);
    > change_int(number);
    > printf("number = %d\n", *number);
    >
    > free(number);
    > system("PAUSE");


    On my system, this call issues the message:

    PAUSE: command not found



    > return 0;
    > }
    >
    > void change_int(int *num)
    > {
    > int *temp;
    >
    > temp = num;
    > num = (int *) malloc(sizeof(int));
    > *num = 15;
    > free(temp);
    > }


    C is a pass-by-value language. Your change_int function does this:

    1) save a pointer to your sizeof(int) bytes, using temp.
    2) allocate some fresh memory, using a local variable (yes, num is local to
    change_int -- it's just a *copy* of the original pointer from main(), and
    will be destroyed on exit).
    3) assign 15 to the storage thus allocated (assuming the allocation request
    didn't fail).
    4) give up the memory you originally allocated in main().
    5) return, in the course of which all local objects are destroyed, including
    your one-and-only pointer to the new block of memory.

    When you get back to main(), you printf("%d\n", *number) - BUT the memory
    that this pointer pointed to was freed in change_int(). So the access is
    invalid.

    Your change_int() function can be rewritten very simply:

    void change_int(int *num)
    {
    *num = 15;
    }

    Try it and see. :)

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Feb 29, 2004
    #5
  6. fix wrote:

    >
    >
    > CViniciusM wrote:
    >
    >> void change_int(int *num)
    >> {
    >> int *temp;
    >>
    >> temp = num;
    >> num = (int *) malloc(sizeof(int));
    >> *num = 15;
    >> free(temp);

    >
    > Just a newbie to C, but I guess this line is the problem.
    > temp and num is pointing to the same allocated memory,
    > you free temp means you free num,


    No, because num has acquired a new value by that time. You are, however,
    right in thinking that this function has BIG problems. :)

    --
    Richard Heathfield :
    "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    K&R answers, C books, etc: http://users.powernet.co.uk/eton
     
    Richard Heathfield, Mar 2, 2004
    #6
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,388
    Martien Verbruggen
    Jun 27, 2003
  2. Hal Styli
    Replies:
    14
    Views:
    1,897
    Old Wolf
    Jan 20, 2004
  3. arun
    Replies:
    8
    Views:
    589
    Dave Thompson
    Jul 31, 2006
  4. aling
    Replies:
    8
    Views:
    1,418
    Jim Langston
    Oct 20, 2005
  5. Replies:
    9
    Views:
    564
    James Kanze
    Apr 17, 2007
Loading...

Share This Page