Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > swap using pointers

Reply
Thread Tools

swap using pointers

 
 
Zach
Guest
Posts: n/a
 
      01-28-2008
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
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      01-28-2008
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
 
Reply With Quote
 
 
 
 
santosh
Guest
Posts: n/a
 
      01-28-2008
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>

 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      01-28-2008
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...
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      01-28-2008
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
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-28-2008
santosh <(E-Mail Removed)> 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) <(E-Mail Removed)>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pointers, pointers, pointers... cerr C Programming 12 04-07-2011 11:17 PM
What swap is called when using std::swap? Niels Dekker (no reply address) C++ 4 07-20-2006 08:44 PM
swap pointers bob@coolgroups.com C++ 1 04-02-2006 07:01 AM
how to swap with pointers ? surrealtrauma C++ 8 05-13-2005 11:12 AM
swap two integers without using a tmp variable? Steve C++ 50 06-25-2004 06:23 PM



Advertisments