when I try to swap these two integers using pointers, I get segmentation fault.
Basically before I swap, x is assigned to 1 and y is assigned to 2. After I swap x is assigned to 2 and y is assigned to 1.
The program takes two integers x and y and is supposedly meant to swap them:
int swap(int x, int y){
int *swapXtoY;
int *swapYtoX;
*swapXtoY = y;
*swapYtoX = x;
}
Function swap is expecting both of its argument as int, but you are passing int *. Compiler should raise a warning about this.
It seems that you have no idea how pointers work in C. Your function is just assigning two ints to local variables. Function should be like:
int swap(int *x, int *y){
int temp;
temp = *x;
*x = *y;
*y = temp;
}
swap method should accept two pointer, instead of two integers.
Try following.
int swap(int* x, int* y){
int temp = *x;
*x = *y;
*y = temp;
}
You must pass variables by address to functions to change their value.That being said,your functions should expect pointers as well.Here is a generic function that can swap variables of any C data type:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void Swap(void *x,void *y,size_t bytes);
int main(void)
{
int x = 3, y = 4;
Swap(&x,&y,sizeof(int));
printf("x now : %d\n",x);
printf("y now : %d\n",y);
return 0;
}
void Swap(void *x,void *y,size_t bytes)
{
void *tmp = malloc(bytes);
memcpy(tmp,x,bytes);
memcpy(x,y,bytes);
memcpy(y,tmp,bytes);
free(tmp);
}
Firstly, your function passes its arguments by value1, which makes it impossible for the function to make any lasting changes to them.
Secondly, the swap idiom consists of:
defining an intermediate variable, temp, which is initializes to one of the two variables, for example x.
assigning the value of the second variable,y to the first (saved in temp) variable x (now temp has value x and x has value y).
finally, assigning temp, to the second variable, y (now x has the value of y and vice versa).
In C code, this would look like:
void swap (int *x, int *y ) {
// dereference x to get its value and assign it to temp
int temp = *x;
// dereference x and assign to it the value of y
*x = *y;
// complete the swap
*y = temp;
}
Then to call the function:
// if the variables are not pointers
swap(&x, &y);
// if variables are passed via pointers
swap(x_ptr, y_ptr);
You might want to check the meaning of the dereference operator * or address-of operator &.
1. By value: it passes a copy of the passed variable, which prevents any change outside the function.
Related
In the function read, I need to access the values of integer a and integer b from the main function without declaring them in the prototype of the function read, using pointers.
Pointer x should point to integer a, and pointer y should point to integer b.
#include <stdio.h>
void read(int zzz[], int n) {
int *arr = zzz, *x=a,*y=b;
}
int main() {
int a, b;
scanf("%d", &a);
scanf("%d", &b);
return 0;
}
How this could be implemented?
There are two ways that the read function can read the values or addresses of a and b:
Pass them as parameters
Make a and b global
So if you don't want to make them parameters, you need to move them outside of the main function and before the read function.
Also, read is the name of a system function, so you should name it something else so you don't conflict with it.
You have already received the more conventional answer. It is the most logical choice for your given restriction.
However ... Silly artificial restrictions sometimes deserve a silly contrived solution in kind.
A less conventional way would be to create an understanding with the function that the values will be passed in with the array pointer in some non-standard way.
For example, you can make two extra array members to represent a and b.
int array_for_my_read[array_size + 2];
/* instead of a and b, you use those extra array members */
...
int *x = zzz + n, *y = x + 1;
Alternatively, you could create a special structure that holds the array, and the pointers. Then the function recovers the pointer to the structure from the array pointer.
struct extra_parameters {
int *a;
int *b;
int zzz[zzz_size];
};
...
struct extra_parameters x;
int a, b;
x.a = &a;
x.b = &b;
read(x.zzz, zzz_size);
...
void *p = (char *)zzz - offsetof(struct extra_parameters, zzz);
struct extra_parameters *xp = p;
int *a = xp->a, *b = xp->b;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
In the code below in order to swap between px and py you need a pointer to point to the address of py and px to swap them effectively.
My question is with the int temp when the value of px is put into it how does it give the correct value back because there is no pointer pointing to it to be able to give the right value and how is the address of int temp not clone to give a wrong value?
void swap(int px, int py)
{
int temp;
temp = px;
px = py;
py = temp;
}
//pointer version
void swap(int *px, int *py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
Both functions swap the int values. But does that swap affect the calling code's ints?
With the second swap(), the effect of the swap is seen in the original a,b as that function works with the addresses of the original a,b.
int a = 1;
int b = 2;
swap_version2(&a, &b);
printf("%d %d\n", a, b); // prints 2 1
With the first swap(), the effect of the swapped is not seen in the original c,d. as the swap() function was swapping copies of c,d. Net effect: the first swap function simply wastes time. It does not swap c,d.
int c = 3;
int d = 4;
swap_version1(c, d);
printf("%d %d\n", c, d); // prints 3 4
There are two important things you need to know.
1) When calling a function in C, the arguments are always passed by value. If you make changes inside the functions to the variables holding the passed value, the changes will be lost the moment the function returns. In other words - any change made inside the function can't be seen outside the function.
2) When working with pointer the * operator in front of the pointer means the location pointed to by the pointer. It is called dereferencing the pointer. So if you do *px = 5; you do not change any pointer value! You change the value at the location pointed to by the pointer.
A closer look at your code:
In your first example you have something like:
void swap(int px, int py)
{
int temp;
temp = px;
px = py;
py = temp;
}
int main(void)
{
int x = 10;
int y = 100;
swap(x, y);
printf("%d %d\n", x, y);
return 0;
}
In C everything is passed by value. So when you call swap it is the values 10 and 100 which is passed to the function. It is not the variables x and y. In other words - px and py in the function has nothing to do with the variable x and y in main. This means that any change made to the variables px and py is lost when the function returns and x and y does not change.
Your second example is like this:
void swap(int px, int py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
int main(void)
{
int x = 10;
int y = 100;
swap(&x, &y); // Notice the & operator
printf("%d %d\n", x, y);
return 0;
}
As always we have pass by value. But in this case the values that you pass is the values of two pointer to int. More specific you pass the address of x and y.
Like before you can't change the value that is passed to the function (just like the first example) but you can change the value of whatever the pointer is pointing to.
Here you need to know that * in front of the pointer access whatever the pointer is pointing to.
So doing temp = *px will read the value pointed to by px. In this case it is 10 so temp gets the value 10.
Doing *px = *py reads the value py points to (i.e. 100) and place it where px points (i.e. x in main is now 100).
Doing *py = temp reads the value temp holds (i.e. 10) and place it where py points (i.e. y in main is now 10).
So when the function returns, the value of x and y has been swapped.
Notice that the code never uses a pointer to (aka the address of) temp. The variable temp is just used as an ordinary int.
In this function
void swap(int *px, int *py)
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}
there are swapped values pointed to by px and py. The function does not swap the pointers themselves.
To swap the values pointed to by the pointers you need an intermediate memory where temporary to store the value pointed to by px that will be overwritten by the value pointed to by py.
Thus the function uses local variable temp that temporary stores the value *px.
Pay attention to that in this assignment statement
temp = *px;
the variable temp stores the value pointed to by px that is *px that has type int. It is not the pointer px itself that is assigned to temp.
Can anyone explain me why am I getting the error
cannot convert int ** to int* of argument1
I have seen all the stack overflow answers but did not find the way to solve my problem. My code
#include<stdio.h>
int* sum(int,int*);
int main()
{
int a=5;
int *b;
*b=6;
int *res;
res=sum(a,&b);
printf("\n%d\n%d\n",a,*b);
printf("%d",*res);
}
int* sum(int x,int *y)
{
x=x+1;
*y=*y+3;
return (&y);
}
This is a basic problem but I am finding it hard to solve the error.
res=sum(a,&b);
Here b is already a pointer(an unallocated integer pointer which may lead to undefined behaviour).So &b is of type int **. So pass only b.
res(a,b);
After that you return &y which is also of int** type change it to y (of type int *)if you want to return the address.
return y;
In your case,
int* sum(int x,int *y)
function accepts an int, an int * and finally returns an int *. Now, inside the function definition, you're writing
return (&y);
here. y is int *, so &y produces int **, which is wrong, as per the defined return type[e of the function.
change
return (&y);
to
return y;
as you're returning an int *, and y is already one.
Next, the same kind of conceptual issue with the function call also. Instead of res=sum(a,&b);, you need to pass b only, as it's already a pointer.
Also, please notice,
the recommended signature of main() is int main(void).
return is not a function. You usually don't need a parenthesis around it's expression, specially, when using a variable name only as the expression.
Can anyone explain me why am I getting the error
Going over your code piece for piece:
int a=5; /* initializes a to value 5 */
int *b; /* declares pointer b */
*b=6; /* OPS, segfault here */
int *res; /* declares pointer res */
res=sum(a,&b); /* assigning to the address of res */
The statement *b = 6; is wrong, you should not do that. You are trying to assign the value 6 to a pointer that is not dynamically allocated, and you haven't set it to point to any address yet.
What you should do is, make the pointer point to the address of a variable first, for example:
int c = 3;
int *b = &c; /* create a pointer 'b' and make that
pointer point to the address of c */
*b = 6; /* OK */
Notice the difference in appearance between initializing int *b = &c;, and declaring and then assigning b = &c:
int *b; /* declaring a pointer 'b' */
b = &c; /* make that pointer point to address of c */
Next, you create a pointer variable 'res' and you try to assign the return value of sum to the address of res:
int *res; /* declaring pointer 'res' */
res = sum(a, &b); /* OPS, 'b' is a pointer */
Looking at the function 'sum', you are trying to make parameter int *y point to the address of b, but the way to do that with pointers is simply to omit the &, therefore passing only b: sum(a, b);
Now, the return value of sum is:
int* sum(int x,int *y) /*
^ sum returns a pointer to int */
And according to your code, you want to assign the result of function sum to the address of res, therefore you want to assign the address of y to the address of res:
res=sum(a,b); /* calling function sum */
int* sum(int x,int *y) /* 'y' points to address of b */
{
x=x+1;
*y=*y+3;
return y; /* returning the address */
}
When sum returns, res points to the same address as y and b.
With pointers assign the address to the address of another pointer, example:
/* a and c are int's */
int *x = &a;
int *y = &c;
x = &y; /* wrong */
While this is correct:
int *x = &a;
int *y = &c;
x = y; /* ok */
Because y is an int* y (pointer to int), then &y is an int** (pointer to int* or pointer to pointer to int), but your function (sum) must return int*, not int**. You just change return &y to return y to fix this.
Here is an example of what I mean. This example is without using pointers and the variables do not swap.
void swap(int x, int y);
main()
{
int a = 33, b = 55;
swap (a, b);
printf("a = %d, b = %d\n", a, b);
}
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
Now if you use pointers the variables a and b swap. Why is it that it only works with pointers?
C is a pass-by-value language. Always. That means with this:
void swap(int x, int y)
{
int temp = x;
x = y;
y = temp;
}
you're swapping the values of x and y, obtained from the values passed to the function. When you invoke like this:
int main()
{
int a = 33, b = 55;
swap (a, b); // passing values of a and b
printf("a = %d, b = %d\n", a, b);
}
the values of a and b are passed. So this is your problem. The solution is to make the values passed something that can be used to modify the caller's variables. If you want to modify those variables they need to somehow be addressable from the called code. Hmmm...
The mechanism is called "pass by address", and though it sounds fancy in reality it isn't. It is simply a retooling of pass-by-value, but with a different value type. Whereas before we were passing values of type int we will instead pass addresses of the integer variables and declare the formal parameters to be pointers to int instead. Make no mistake. They're still values, but not of the basic int type. Rather the values passed are addresses of int variables. To access the data at those addresses pointers are used in conjunction with the dereference operator (of which there are several kinds, only one shown here):
void swap(int *ptrToX, int *ptrToY)
{
int temp = *ptrToX; // dereference right, store value in temp
*ptrToX = *ptrToY; // dereference both, assigning value from right to left.
*ptrToY = temp; // dereference left, assign temp value
}
and invoked like this:
int main()
{
int a = 33, b = 55;
swap (&a, &b); // passing addresses of a and b
printf("a = %d, b = %d\n", a, b);
}
Note: Often ill-quoted as the exception to pass-by-value is passing an array. Though the phrase "decays to a pointer" is thrown about like confetti on New Years Eve, I abhor that vernacular. The verb itself implies a functional operation where there is, in fact, none.
The language specifies the value of an array used in an expression is the address of its first element. In other words, its "value" is already an address and as such can simply be passed by-value to a function expecting a pointer to the same base type. Because it is an address, the receiving parameter (a pointer, because thats what holds address values) can then be used to modify the array content from the caller. Second only to multiple levels of indirection (pointers to pointers, etc) it is easily the hardest thing for people new to C to wrap their head around, yet it is important you do so.
When you call swap, the value of the variables a and b are passed to it. These values are passed by copy. When you swap those values in swap, you are only swapping local copies of a and b.
When you pass pointers to variables to a function, you are able to modify the values of the variables in the calling function.
That's called pass by value.
You are just passing values of a & b to the swap function. The swap function copies that value into its variables x & y which are different from a & b. Hence in swap you are working on x & y instead of a & b.
On the other hand, when you pass pointers, you are passing the address where a & b are stored. Your x & y point to the same address and hence you are manipulating the content at that address where a & b are stored. Hence, main gets to see the updated values.
This is the best example to define the advantage/use of function call by reference V/s call by value
In the main() function the two variables has the value
int a = 33, b = 55;
so using these variables in the swap(a,b) function, it just passes the values to the function definition where
void swap(int x, int y)
{
int temp;
temp = x;
x = y;
y = temp;
}
they declare again two variables x,y and the values in this variables are swapped. But the variables x and y are only known to function swap() after execution of the swap() function that variables are no longer valid. So nothing happens to the variables a,b in the main function.
So in order to swap variables using function you've to use
swap(&a,&b);
in main() function , and modify function swap()
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
Which passes the address of variables a and b , and the pointers are used to swap the variables,It gets swapped effectively. Since pointer points to the address of the variables the value of the variables get changed.
For more google "call by referece and call by value in c"
I'm new to C and still trying to grasp the concept of pointers. I know how to write a swap function that works...I'm more concerned as to why this particular one doesn't.
void swap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(a, b);
printf(ā%d %d\nā), *a, *b);
}
You're missing *s in the swap function. Try:
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
That way, instead of just swapping the pointers, you're swapping the ints that the pointers are pointing to.
Your swap() function does work, after a fashion - it swaps the values of the variables a and b that are local to swap(). Unfortunately, those are distinct from the a and b in main() - so you don't actually see any effect from swapping them.
When thinking about pointers, you need to be clear on a few abstractions.
An object in memory. This can be of any type (and size). An integer object, for example, will occupy 4 bytes in memory (on 32 bit machines). A pointer object will occupy 4 bytes in memory (on 32 bit machines). As should be obvious, the integer object holds integer values; a pointer object holds addresses of other objects.
The C programming language lets symbols (variables) represent these objects in memory. When you declare,
int i;
the symbol (variable) i represents some integer object in memory. More specifically, it represents the value of this object. You can manipulate this value by using i in the program.
&i will give you the address of this object in memory.
A pointer object can hold the address of another object. You declare a pointer object by using the syntax,
int* ptr;
Just like other variables, the pointer variable represents the value of an object, a pointer object. This value just happens to be an address of some other object. You set the value of a pointer object like so,
ptr = &i;
Now, when you say ptr in the program, you are referring to its value, which is the address of i. But if you say *ptr, you are referring to not the value of ptr, but rather the value of the object whose address is in ptr i.e. i.
The problem with your swap function is that you are swapping values of pointers, not the values of objects that these pointers hold addresses for. To get to the values of objects, you would have to use *ptr.
C is a pass-by-value language. Your swap routine doesn't dereference the pointers passed to it, so from main's perspective nothing has happened.
The pointers are passed by value. This means a & b are still a and b when the come back from the function;
try something like this
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
The right way to do it:
void swap(int* a, int* b)
{
int temp = *a; // Temp is set to the value stored at a (5)
*a = *b; // value stored at a is changed to the value stored at b (10)
*b = temp; // value stored in address b is changed to 5.
}
It does swap. It swaps local pointers a and b inside swap function. It swaps them perfectly fine, as it should.
If you want to swap the values these pointers are pointing to, you should re-implement your swap function accordingly, i.e. make it swap the pointed values, not the pointers.
Umm maybe using this
void swap(int** a, int** b)
{
int** temp = a;
a = b;
b = temp;
}
int main()
{
int x = 5, y = 10;
int *a = &x, *b = &y;
swap(&a, &b);
printf(ā%d %d\nā), *a, *b);
}
Without using a third variable (temp)
void swap(int* a,int* b)
{
// a = 10, b = 5;
*a = *a + *b; // a now becomes 15
*b = *a - *b; // b becomes 10
*a = *a - *b; // a becomes 5
}
zildjohn1's answer is the easiest and clearest way to do it. However if you insist on swapping the pointers, then you have to pass the pointer to the pointer because the pointer itself is passed by value.
You need to send the address of a and b for swap function so while calling swap function you must call ass swap (&a,&b)
So that you pass the address, and alter the address
#define SWAP(a,b) ((a)=(b)+(a),(b)=(a)-(b),(a)=(a)-(b))
Works good.