swap using pointers

Discussion in 'C Programming' started by Zach, Jan 28, 2008.

  1. Zach

    Zach Guest

    I am working on a new version of my swap program [1] that uses
    pointers. It seems to work fine but I have some points I would like
    clarifying.

    Here is the code:

    /* swap-foo2.c: swap 2 integers
    * Zach
    * 01/27/08, version 2
    */

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

    int swap(int*, int*);

    int *s1, *s2;

    int main(void)
    {

    s1 = 3;
    s2 = 4;

    printf("s1 = %d \n", s1);
    printf("s2 = %d \n", s2);

    swap(s1,s2);

    exit(EXIT_SUCCESS);

    }

    int swap(int *s1, int *s2)
    {
    int temp;

    temp = s1;
    s1 = s2;
    s2 = temp;

    printf("s1 = %d \n", s1);
    printf("s2 = %d \n", s2);

    return s1,s2;

    }

    When I compile and run it:

    zu22@netrek:~/src/myc$ gcc -g -o foo swap-foo2.c
    swap-foo2.c: In function 'main':
    swap-foo2.c:16: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:17: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c: In function 'swap':
    swap-foo2.c:32: warning: assignment makes integer from pointer without
    a cast
    swap-foo2.c:34: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:39: warning: return makes integer from pointer without a
    cast

    zu22@netrek:~/src/myc$ ./foo
    s1 = 3
    s2 = 4
    s1 = 4
    s2 = 3

    I had been told by a member of this group, Joachim Schmitz, to call my
    swap function with the address of my two variables:
    swap(&s1,&s2);

    However when I do this it gives some new warnings and a strange
    result:

    zu22@netrek:~/src/myc$ gcc -g -o foo swap-foo2.c
    swap-foo2.c: In function 'main':
    swap-foo2.c:16: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:17: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:22: warning: passing argument 1 of 'swap' from
    incompatible pointer type
    swap-foo2.c:22: warning: passing argument 2 of 'swap' from
    incompatible pointer type
    swap-foo2.c: In function 'swap':
    swap-foo2.c:32: warning: assignment makes integer from pointer without
    a cast
    swap-foo2.c:34: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:39: warning: return makes integer from pointer without a
    cast

    zu22@netrek:~/src/myc$ ./foo
    s1 = 3
    s2 = 4
    s1 = 134518352
    s2 = 134518348

    Why is this? I'm doing this to help advance my understanding of
    pointers and passing parameters to functions. Can someone explain what
    all these warnings mean?

    BTW on lines 16, 17 where I assign values to the pointers why can't I
    do this:
    *s1 = 3;
    *s2 = 4;

    When I do it causes a core dump:

    zu22@netrek:~/src/myc$ gcc -g -o foo swap-foo2.c
    swap-foo2.c: In function 'main':
    swap-foo2.c:22: warning: passing argument 1 of 'swap' from
    incompatible pointer type
    swap-foo2.c:22: warning: passing argument 2 of 'swap' from
    incompatible pointer type
    swap-foo2.c: In function 'swap':
    swap-foo2.c:32: warning: assignment makes integer from pointer without
    a cast
    swap-foo2.c:34: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:39: warning: return makes integer from pointer without a
    cast

    zu22@netrek:~/src/myc$ gdb ./foo
    GNU gdb 6.6.90.20070912-debian
    Copyright (C) 2007 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/
    gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law. Type "show
    copying"
    and "show warranty" for details.
    This GDB was configured as "i486-linux-gnu"...
    Using host libthread_db library "/lib/libthread_db.so.1".
    (gdb) run
    Starting program: /home/zu22/src/myc/foo
    Failed to read a valid object file image from memory.

    Program received signal SIGSEGV, Segmentation fault.
    0x080483ba in main () at swap-foo2.c:16
    16 *s1 = 3;
    (gdb) bt
    #0 0x080483ba in main () at swap-foo2.c:16
    (gdb) quit
    The program is running. Exit anyway? (y or n) y

    I've seen pointer values assigned in this way with type char as in:
    char *string = "hello";
    So why is this illegal with type int?

    Also I noticed if I print out the values of my pointer variables in
    main after the call to swap they are still the same. My understanding
    was that since I declared them as global variables they had global
    scope and when swap returns the new values they should be changed but
    it seems they aren't here:

    /* swap-foo2.c: swap 2 integers
    * Zach
    * 01/27/08, version 2
    */

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

    int swap(int*, int*);

    int *s1, *s2;

    int main(void)
    {

    s1 = 3;
    s2 = 4;

    printf("s1 = %d \n", s1);
    printf("s2 = %d \n", s2);

    swap(s1,s2);

    printf("s1 = %d \n", s1);
    printf("s2 = %d \n", s2);

    exit(EXIT_SUCCESS);

    }

    int swap(int *s1, int *s2)
    {
    int temp;

    temp = s1;
    s1 = s2;
    s2 = temp;

    return s1,s2;

    }

    zu22@netrek:~/src/myc$ gcc -g -o foo swap-foo2.c
    swap-foo2.c: In function 'main':
    swap-foo2.c:16: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:17: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c: In function 'swap':
    swap-foo2.c:35: warning: assignment makes integer from pointer without
    a cast
    swap-foo2.c:37: warning: assignment makes pointer from integer without
    a cast
    swap-foo2.c:39: warning: return makes integer from pointer without a
    cast

    zu22@netrek:~/src/myc$ ./foo
    s1 = 3
    s2 = 4
    s1 = 3
    s2 = 4

    My understanding is that in the following code:

    int main(void)
    {

    int *p; /* or "int* p" declares a variable p pointing to type int */

    int q; /* declares variable q of type int */

    p = 3; /* assigns the integer 3 as the pointer-value */

    foo(&p): /* the function foo calls the address of the pointer p's
    location in memory,
    by using the address-of operator &.
    this represents the starting bit of where it is layed
    out in memory */

    q = *p; /* assigns the pointer-value to point to variable q,
    by using the dereferencing operator *. */

    }

    Are all my comments correct?

    PS: I noticed in "man 3 printf" that %p is for pointers and not %d but
    when I use that it prints my results in hexadecimal such as:
    s1 = 0x3
    s2 = 0x4

    [1] http://tinyurl.com/2zh5mj

    Regards,
    Zach
     
    Zach, Jan 28, 2008
    #1
    1. Advertising

  2. Zach said:

    > I am working on a new version of my swap program [1] that uses
    > pointers. It seems to work fine but I have some points I would like
    > clarifying.
    >
    > Here is the code:


    Here is the fixed code:

    /* swap-foo3.c: swap 2 integers
    * rjh - changes are marked.
    * 01/28/08, version 3
    */

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

    int swap(int*, int*);

    int main(void)
    {

    int s1 = 3; /* int, not int *, okay? */
    int s2 = 4; /* and again */

    printf("Before swap, s1 = %d\n", s1); /* clarify meaning */
    printf("Before swap, s2 = %d\n", s2); /* of print */

    swap(&s1, &s2); /* pass addresses */

    printf("After swap, s1 = %d\n", s1); /* display results */
    printf("After swap, s2 = %d\n", s2); /* after swap */

    exit(EXIT_SUCCESS); /* this is okay, but I'd prefer return 0; */

    }

    int swap(int *s1, int *s2)
    {
    int temp;

    temp = *s1; /* we're swapping the values of the objects pointed to */
    *s1 = *s2; /* To get to those values, we use the *deref operator */
    *s2 = temp; /* here too */

    return 0; /* I don't know why you thought you could return s1,s2 */
    }

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jan 28, 2008
    #2
    1. Advertising

  3. Zach

    santosh Guest

    Zach wrote:

    > I am working on a new version of my swap program [1] that uses
    > pointers. It seems to work fine but I have some points I would like
    > clarifying.
    >
    > Here is the code:
    >
    > /* swap-foo2.c: swap 2 integers
    > * Zach
    > * 01/27/08, version 2
    > */
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int swap(int*, int*);
    >
    > int *s1, *s2;
    >
    > int main(void)
    > {
    >
    > s1 = 3;
    > s2 = 4;


    This invokes implementation specific behaviour. Integers are not
    automatically convertible to pointer values. At a minimum, you need to
    use a cast. However you'll find that for most modern desktop operating
    systems, the code will still malfunction, even after a cast.

    In general you cannot use an arbitrary memory address under memory
    protected multitasking OSes. You must let the compiler and runtime
    library take of such stuff and initialise pointers only to the address
    yielded by the address-off operator '&' applied on an object of
    compatible type and scope, or assign the return value of the *alloc()
    functions, malloc(), calloc() or realloc().

    > printf("s1 = %d \n", s1);
    > printf("s2 = %d \n", s2);


    The format specifier for printing pointer values is 'p'. It accepts a
    void * value. Use like:

    printf("s1 = %p\n", (void *)s1);

    > swap(s1,s2);


    Not only are you accessing arbitrarily chosen addresses (which will most
    likely lead to a segmentation fault under most desktop OSes), but you
    are accessing indeterminate values as well.

    >
    > exit(EXIT_SUCCESS);
    >
    > }
    >
    > int swap(int *s1, int *s2)
    > {
    > int temp;
    >
    > temp = s1;


    This should be:

    temp = *s1;

    > s1 = s2;


    *s1 = *s2;

    > s2 = temp;


    *s2 = temp;

    >
    > printf("s1 = %d \n", s1);
    > printf("s2 = %d \n", s2);


    These should be:

    printf("s1 = %d\n", *s1);
    ditto

    >
    > return s1,s2;


    Huh? What the hell is the purpose of this? s1 and s2 are both int *
    values, but you define swap() as returning an int value. At a minimum
    you need to do:

    return *s1, *s2;

    This is still silly in the sense that this will evaluate *s1 and discard
    the value, returning *s2;

    >
    > }
    >
    > When I compile and run it:
    >
    > zu22@netrek:~/src/myc$ gcc -g -o foo swap-foo2.c


    Also use the '-Wall', '-W', '-ansi' and '-pedantic' switches. They will
    tell gcc to conform strictly to C95 and turn on a lot of diagnostics
    (though not all).

    Please read a good textbook on C like K&R2 or a good online tutorial
    like Steve Summit' or Tom Torf' before proceeding. You are making
    several fundamental errors that a good book or tutorial can more easily
    correct than a newsgroup.

    <rest snipped>
     
    santosh, Jan 28, 2008
    #3
  4. Zach

    Mark Bluemel Guest

    santosh wrote:

    > Please read a good textbook on C like K&R2 or a good online tutorial
    > like Steve Summit' or Tom Torf' before proceeding. You are making
    > several fundamental errors that a good book or tutorial can more easily
    > correct than a newsgroup.


    We do seem to have a certain proportion of posters who believe that C
    programming can be successfully learnt by trial and error, supplemented
    by posting their code - which bears a passing resemblance to C,
    indicating that they've seen some C code but not understood it - to this
    newsgroup...
     
    Mark Bluemel, Jan 28, 2008
    #4
  5. Zach

    pete Guest

    Richard Heathfield wrote:
    >
    > Zach said:
    >
    > > I am working on a new version of my swap program [1] that uses
    > > pointers. It seems to work fine but I have some points I would like
    > > clarifying.
    > >
    > > Here is the code:

    >
    > Here is the fixed code:
    >
    > /* swap-foo3.c: swap 2 integers
    > * rjh - changes are marked.
    > * 01/28/08, version 3
    > */
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int swap(int*, int*);
    >
    > int main(void)
    > {
    >
    > int s1 = 3; /* int, not int *, okay? */
    > int s2 = 4; /* and again */
    >
    > printf("Before swap, s1 = %d\n", s1); /* clarify meaning */
    > printf("Before swap, s2 = %d\n", s2); /* of print */
    >
    > swap(&s1, &s2); /* pass addresses */
    >
    > printf("After swap, s1 = %d\n", s1); /* display results */
    > printf("After swap, s2 = %d\n", s2); /* after swap */
    >
    > exit(EXIT_SUCCESS); /* this is okay, but I'd prefer return 0; */
    >
    > }
    >
    > int swap(int *s1, int *s2)
    > {
    > int temp;
    >
    > temp = *s1; /* we're swapping the values of the objects pointed to */
    > *s1 = *s2; /* To get to those values, we use the *deref operator */
    > *s2 = temp; /* here too */
    >
    > return 0; /* I don't know why you thought you could return s1,s2 */
    > }


    It should really be
    void swap(int *s1, int *s2)
    There is no information in the return value from that function.

    --
    pete
     
    pete, Jan 28, 2008
    #5
  6. santosh <> writes:
    > Zach wrote:

    [...]
    >> int *s1, *s2;
    >>
    >> int main(void)
    >> {
    >>
    >> s1 = 3;
    >> s2 = 4;

    >
    > This invokes implementation specific behaviour. Integers are not
    > automatically convertible to pointer values. At a minimum, you need to
    > use a cast. However you'll find that for most modern desktop operating
    > systems, the code will still malfunction, even after a cast.


    This doesn't merely invokes implementation specific behavior.
    Attempting to assign an int value (other than a constant 0) to a
    pointer is a constraint violation. There is no implicit conversion
    from integers to pointers or vice versa, except for ones involving
    null pointer constants. *If* the implementation chooses to accept the
    assignments (after issuing a mandatory diagnostic), the behavior is
    undefined by the standard; it might not even do a conversion.

    As Richard points out, the proper solution isn't for the OP to
    understand the gory details of just how and why the assignments are
    wrong and exactly what effect they can have, it's to write the correct
    code in the first place.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 28, 2008
    #6
    1. Advertising

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. Steve
    Replies:
    50
    Views:
    26,878
  2. surrealtrauma

    how to swap with pointers ?

    surrealtrauma, May 12, 2005, in forum: C++
    Replies:
    8
    Views:
    3,440
    Karl Heinz Buchegger
    May 13, 2005
  3. swap pointers

    , Apr 2, 2006, in forum: C++
    Replies:
    1
    Views:
    429
    Alf P. Steinbach
    Apr 2, 2006
  4. Niels Dekker (no reply address)

    What swap is called when using std::swap?

    Niels Dekker (no reply address), Jul 19, 2006, in forum: C++
    Replies:
    4
    Views:
    1,007
    Niels Dekker (no reply address)
    Jul 20, 2006
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    715
Loading...

Share This Page