C Pointer Not Being Set Equal to Another - c

void s(int* a, int* b) {
a=b;
}
int main(int argc, char* argv[]) {
int* a = malloc(sizeof(int));
int* b = malloc(sizeof(int));
int c = 10;
int d = 5
a = &c;
b = &d;
printf("%d %d\n",*a,*b);
s(a,b);
printf("%d %d\n",*a,*b);
}
I am so very confused. This is very simple code. I thought that this would result in a and b pointing to the same value. When i do a=b inside of the main function everything works as expected. When I use gdb it even shows that they point to the same place in memory and the function is not being optimized away!!! So what is happening?
Is the function creating its own local copy? Why don't these point to the same variable please help.

You want to change the pointers values. Pointers are passed by value, so you need a pointer to the pointer to change its value:
#include <stdio.h>
void s(int** foo, int** bar)
{
*foo = *bar;
}
int main(void)
{
int c = 10;
int d = 5;
int *a = &c;
int *b = &d;
printf("%d %d\n", *a, *b); // 10 5
s(&a, &b);
printf("%d %d\n", *a, *b); // 5 5 a points at d as well
}
With your version you only changed the parameters which are copies of the values passed to the function.
To help you better understand, consider this:
#include <stdio.h>
void value(int foo, int bar)
{
foo = bar; // changing local copies
}
void pointer(int *foo, int *bar)
{
*foo = *bar; // changing the value foo points to to the value bar points to
}
int main(void)
{
int a = 5;
int b = 7;
value(a, b);
printf("%d, %d\n", a, b); // 5, 7
pointer(&a, &b);
printf("%d, %d\n", a, b); // 7, 7
}
We did that with the type int. Now lets just replace int with int*:
#include <stdio.h>
void value(int *foo, int *bar)
{
foo = bar; // changing local copies
}
void pointer(int **foo, int **bar)
{
*foo = *bar; // changing the value foo points to to the value bar points to
}
int main(void)
{
int x = 5;
int y = 7;
int *a = &x;
int *b = &y;
value(a, b);
printf("%d, %d\n", *a, *b); // 5, 7
pointer(&a, &b);
printf("%d, %d\n", *a, *b); // 7, 7 now both point at y
}
So you see, it's the same concept both times. In the first example the values pointed to are ints and their values are numbers, in the second example the values pointed to are int*s and their values are pointer values (<~ standard terminology, "addresses"). But the mechanism is the same

You program is almost correct but you need to pass the address of the variables in the function as you using call by refrence and in the function take pointer to pointers.

Related

Pointer to pointer in c source file

I see a code which says the following.
typedef struct dummy
{
int a;
int b[100];
} dummy_t;
typedef struct dummya
{
int a;
int b;
} dummya_t;
void * getptr(){
// return a pointer of a memory
}
void function(){
dummya_t*dstptr = getptr();
dummy_t *srcpt = (dummy_t*)(dstptr->b);
}
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
Your code is not correct, you can not cast nor assign using pointers to objects of different types, for example:
struct a { int a, b; };
struct b { int a, b; };
are different objects even having the same members.
struct a x = {.a = 1, .b = 2};
struct b *y = &x; // wrong
I can see dummy_t srcpt = (dummy_t)(dstptr->b); meaning as a pointer
is pointing to another pointer but then *srcpt should be a double
pointer right? Like **srcpt
Your assumptions are not correct, a basic example using plain pointers to int:
#include <stdio.h>
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
int **ptr;
ptr = &a;
*ptr = &arr[1];
ptr = &b;
*ptr = &arr[0];
printf("a = %d b = %d\n", *a, *b);
return 0;
}
The output is:
a = 1 b = 2
a = 2 b = 1
As you can see, you use a double pointer (**ptr) when you want to change the contents of a or b (the address where it points to), a more useful example:
#include <stdio.h>
void swap(int **a, int **b)
{
int *temp = *a;
*a = *b;
*b = temp;
}
int main(void)
{
int arr[] = {1, 2};
int *a = &arr[0];
int *b = &arr[1];
printf("a = %d b = %d\n", *a, *b);
swap(&a, &b);
printf("a = %d b = %d\n", *a, *b);
return 0;
}
Same output:
a = 1 b = 2
a = 2 b = 1
I can see dummy_t *srcpt = (dummy_t*)(dstptr->b); meaning as a pointer is pointing to another pointer but then *srcpt should be a double pointer right? Like **srcpt
No. That line means "treat the value of dstptr->b as though it were a value of type dummy_t *, and assign it to srcpt". It's not a pointer to a pointer.
The expression dstptr->b has type int, which cannot be directly assigned to a pointer type. (dummy_t *) is a cast, which tells the compiler to convert the type.
Like Vlad says in his comment, this code doesn't make any sense. It may compile, but just because it compiles doesn't mean it's right.

C Passing and Reassinging Pointers in Functions

Here's the function in question. Why does x not change, despite having ptr reference it's memory address? Similarly why doesn't y change?
#include <stdio.h>
int func (int a, int *b)
{
int *ptr = &a;
*ptr += 5;
ptr = b;
*ptr -= 3;
return a;
}
int main ()
{
int x = 2;
int y = 8;
int ret = func (x, &y);
printf ("x: %d\n", x);
printf ("y: %d\n", y);
printf ("ret: %d\n", ret);
return 0;
}
Edit: yes y does change. Sorry.
int func (int a, int *b)
'a' is passed by value. Inside func() a has its own memory allocated, so anything you do to it does not affect the variable that was passed in. 'b' is a pointer to an int so changing the data at that address is still visible outside the scope of func(). Hence, x doesn't change, but y does.

Pointers and Address in C

I write a C program. I have 2 pointers *a and *b. Now, I impose *a = 20 and *b = 10. After that I impose a = b in subroutine but the value seem doesn't change. I expect that *a = 10 and *b = 10. Please help me find a solution for this. Thank you.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void Copy(int *a1, int *a2)
{
a1 = a2;
}
void Test()
{
// a = 20
int *a = (int *)malloc(sizeof(int));
*a = 20;
// b = 10
int *b = (int *)malloc(sizeof(int));
*b = 10;
Copy(a, b); // a = b
printf("\na = %d", *a);
printf("\nb = %d", *b);
}
int main(int argc, char *argv[]){
Test();
fflush(stdin);
printf("\nPress any key to continue");
getchar();
return 0;
}
Function arguments are passed by value. So inside the function Copy you are modifying a copy of the pointer not the original pointer you had in the Test function. So when you leave the Copy function the pointers outside are not modified.
Change the Copy to receive a int **, so you can change inside the value of pointers
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
And call the function in this way:
void Test() {
...
Copy (&a, &b);
...
}
If you want to assign the values, such that after the call of Copy *a == *b holds, then you'd have to change your function as follows:
void Copy(int *a1, int *a2)
{
*a1 = *a2;
}
If you want to assign the pointers, such that after the call of Copy a==b holds, then you have to pass a pointer to the pointers:
void Copy(int **a1, int **a2)
{
*a1 = *a2;
}
void Test() {
...
Copy (&a, &b);
...
}
Note that a==b also implies that *a == *b.

Swap Issue in C [Beginner] [duplicate]

This question already has answers here:
Why does this code not swap the numbers? [duplicate]
(2 answers)
Closed 6 years ago.
I am asked to make a swap between 2 integers.
#include <stdio.h>
#include <stdlib.h>
void swaplol(int a, int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
printf("After the swap : a= %d, b=%d\n",a,b);
}
I dont see where the problems lies. Everything seems good synthax wise...
int main(void)
{
int a,b;
a = 666;
b = 998;
printf("Before the swap a = %d, b = %d\n",a,b);
swaplol(a,b);
return 0;
}
Thanks
You need to pass the address of the integer to the swap function, so that when the value is swapped, you get swapped a and b values back in main. You therefore have to change the swaplol function to accept pointers instead of ints.
#include <stdio.h>
#include <stdlib.h>
void swaplol(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
printf("After the swap : a= %d, b=%d\n",*a,*b);
}
int main(void) {
// your code goes here
int a,b;
a = 666;
b = 998;
printf("Before the swap a = %d, b = %d\n",a,b);
swaplol(&a,&b);
printf("After the swap : a= %d, b=%d\n",a,b);
return 0;
}
The swap function should swap values of the original variables declared in main.
To do this the function has to accept the variables by reference.
And you should remove the output statement from the function and place it in main to demonstrate that the original variables were swapped.
For example
#include <stdio.h>
void swaplol( int *a, int *b )
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main( void )
{
int a, b;
a = 666;
b = 998;
printf( "Before the swap a = %d, b = %d\n", a, b );
swaplol( &a, &b );
printf( "After the swap : a = %d, b = %d\n", a, b );
return 0;
}
There is no need to include header <stdlib.h>
Use pointers:
void swaplol( int * a, int * b )
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main(void)
{
int a, b;
a = 666;
b = 998;
printf( "Before the swap a = %d, b = %d\n", a ,b );
swaplol( &a, &b);
printf( "After the swap : a= %d, b=%d\n", a, b );
return 0;
}
Just add pointers.. i'm providing a code snippet without using a temp variable.
int main()
{
....
....
swaplol(&a,&b);
}
int swaplol(int *a,int *b)
{
*a=*a+*b;
*b=*a-*b;
*a=*a-*b;
printf("a=%d,b=%d",a,b);
}
In C there is The call by value and call by address with help of the Pointers. There you can "simulate" a call by reference which is present in other Languages.
Any way by default, C uses call(pass) by value to pass arguments. This means that the code within a function cannot alter the arguments used to call the function.
Lets take the following example:
#include <stdio.h>
void foo( int x );
int main( void ){
int x = 5;
foo(x);
printf("X = %d\n", x);
}
void foo( int x ){
x = 10;
}
The output will be 5.
If you are using a good compiler with settings turned ON you will see this kind of warning:
program.c:14:15: error: parameter ‘x’ set but not used [-Werror=unused-but-set-parameter]
void foo( int x ){
^
Now what did just happen?
By definition, call(pass) by value means you are making a copy in memory of the actual parameter's value that is passed in, a copy of the contents of the actual parameter.
If you really need to modify a value you need to pass the address of that variable and use a pointer to point to it:
#include <stdio.h>
void foo( int *x );
int main( void ){
int x = 5;
foo(&x);
printf("X = %d\n", x);
}
void foo( int *x ){
*x = 10;
}
Now the Output will be 10.

Dynamically allocating in main() VS in a funtion

int foo(int *p){
p = malloc(sizeof(int));
*p = 20;
}
int main(){
int a;
int *x;
x = &a;
foo(x);
printf("%d \n", a);
return 0;
}
So I'm trying to point at a and then set the value of what x is pointing to 20. However whenever I allocate the pointer in the function I get a random number being printed. Do you know why this happens compared to allocating it in main()?
Thanks
You don't want to allocate in the foo function at all. This is like doing:
void foo(int p) {
p = 2;
printf("%d\n", p);
}
int main() {
int a=1;
foo(a);
return 0;
}
And asking why it didn't print 1. The answer is, you're writing over the pointer to a, so you no longer have a pointer to a when you do *p = 20;.
So I'm trying to point at a and then set the value of what x is pointing to 20
This doesn't make sense given the context of your question. You are pointing x at a, and if you want to change the value of a, then why are you dynamically allocating anything at all? a is already automatically allocated in main(). If you want to dynamically allocate something, what you you need a for at all?
To change the value of a, just pass a pointer to it and forget about malloc():
void foo(int * p)
{
*p = 20;
}
int main(void)
{
int a;
foo(&a);
printf("%d\n", a);
return 0;
}
If you want to dynamically allocate, forget about a, and don't modify it through a passed pointer - return the pointer:
int * foo(void)
{
int * p = malloc(sizeof *p);
if ( !p ) {
perror("could not allocate memory");
exit(EXIT_FAILURE);
}
*p = 20;
return p
}
int main(void)
{
int * x = foo();
printf("%d\n", *x);
free(x);
return 0;
}

Resources