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.
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;
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.
The value in the printf hasn't changed after applying the void function f, which is confusing me. It's basic stuff revolving pointers. The exact question is: Why isn't the end value 2 instead of 1?
int a=1, b=2;
void f(int* p) {
p=&b;
}
int main() {
int *p=&a;
f(p);
printf("%d\n", *p);
}
The *p value in main remains 1, and that's what's confusing me.
You need to dereference p and remove the & address operator from b
This assigns the value of b to the address where p points to:
void f(int* p)
{
*p = b;
}
The reson why it printed 1 and not e.g. the address of b is that you assigned: p = &b which just assigns the address of b to the local pointer variable p. This means it does not point to a anymore here. But since this was just a local copy it didn't change the value of the p you passed in main().
This makes it a little more obvious:
void f(int* ptr)
{
// assign a value
*ptr = 1337;
}
int main()
{
int local_integer = 666;
// prints "666"
printf("%d\n", local_integer);
f(&local_integer);
// prints "1337"
printf("%d\n", local_integer);
}
In your code you define a pointer to int on the stack. Its value is the same as the pointer in the main() function which happens to point to the Ä…ddress of the variable a. Then you change its value (so the pointer on the stack now points to b) then you just drop that pointer.
void f(int* p) {
p=&b;
}
That is why if you dereference the pointer in main it still points to the address of the int variable a.
I am trying to understand why that code crash:(CodeBlocks C99)
int a;
int **b=0;
*b=&a;
I know that *b is of type int* and &a is also int* so what's the problem here?
Let's take this apart:
int a; /* make a an integer, assuming this is in a function on the stack */
int **b=0; /* make b a pointer to a pointer to an integer, but make it point to 0 */
*b=&a; /* store the address of a at the address pointed to by b, which is 0 */
IE you are explicitly writing the address of a to a zero location. The problem is not type compatibility, it's that you are trying to store something at location zero, which will cause a seg fault.
To fix it do something like:
int a; /* make a an integer, assuming this is in a function on the stack */
int *c = 0; /* make an integer pointer, initialise it to NULL */
int **b=&c; /* make b a pointer to a pointer to an integer, make it point to c */
*b=&a; /* store the address of a at the address pointed to by b, which is c */
b points to a pointer, you point the pointer to 0 / NULL, meaning when you do *b = you are assigning the value to address 0 which will die on most OSs ( on embedded systems this can be valid depending on the processor)
You are dereferencing the NULL-Pointer. b points to NULL and in the next line you are dereferencing it and assigning it a new value.
You are not allowed to write to memory you don't own, and you are especially not allowed to write to NULL.
You cannot set pointers to values like that (*b=&a) because they are at the time not pointing to anything; in order to set their value they must be pointing to something.
int a;
int *tmp;
int **b = &tmp;
*b = &a; //this should work because you are setting a real variable (in this case tmp) to &a
Your int **b=0 is a pointer to int *, that is initialized to NULL, and isn't pointing at an allocated storage area. When you write to *b, you are attempting to dereference a null pointer, which is illegal.
If you were to allocate storage, for example using b=malloc(sizeof(*b)), you would then be able to write into the area pointer at by b using *b=&a, because then *b would be a valid address to write into.
#include <stdlib.h>
int
main()
{
int a;
int **b = (int**)malloc(1 * sizeof(int));
*b = &a;
free(b);
return 0;
}
Your *b = &a has the same effect of b[0] = &a.
Something I stumbled upon and made me wonder.
Why does this work?
void foo (int* a)
{
int x = 3;
*a = x;
}
int main()
{
int a;
foo(&a);
return 0;
}
But this causes a segmentation fault (both on Visual Studio 2008 and gcc)?
void foo (int* a)
{
int x = 3;
*a = x;
}
int main()
{
int* a;
foo(a);
return 0;
}
Is it something defined in the language or just an implementation issue?
When you declare
int* a;
You are declaring a pointer variable a but you are not making it point to anything. Then in the function, you do
*a = x;
Which dereferences the pointer and tries to assign what it points to the value of x. But since it doesn't point to anything, you get undefined behaviour, manifested in a segmentation fault.
You should do this:
int i; // the actual integer variable
int* a = &i; // a points to i
The difference between that and the first one is that int a; declares a real integer variable, then you take its address with &a and passes it to the function. The pointer a inside the function foo points to the variable a in main, and so dereferencing it and assigning to it is perfectly fine.
int a;
Assigns memory as soon as you declare it but this not the case with int *a;
int *a;
is pointer declaration (MEMORY not yet allocated for that).
int *a = (int*)malloc(sizeof(int)); // allocate memory