Why Does Changing Pointer Assignments in C Affect Variable Values?

In summary, the code creates a pointer (ptr) that stores the address of integer a and sets it to the value of 2. This changes the value of a to 2. However, when *ptr is used, it means to store a value in the location where the pointer points, which is variable a. Therefore, *ptr = b changes the value of a to 2. The statement ptr = &b is equivalent to ptr = b, as C automatically casts to a pointer type if the r-value is not a pointer type.
  • #1
kidsasd987
143
4
int main(void)

{
int *ptr;
int a=1, b=2, c=3;

ptr = &a;
printf("%p\n", &ptr);

printf("%p\n", &b);

printf("%p\n", &c);

ptr = b;

printf("%p\n", ptr);

printf("%d\n", a);

system("PAUSE");
return 0;


}



ok here is the code I wrote.

ptr(the pointer that stores the address of integer a) is assigned the value 2, and now points the address 2.

therefore a value is still 1.




but somehow when I changed the red colored part to

*ptr=b, now a has a value of 2.

when I change *ptr=&b, a has a weird large value.


could you guys explain me why this happens?
 
Technology news on Phys.org
  • #2
kidsasd987 said:
but somehow when I changed the red colored part to

*ptr=b, now a has a value of 2.

Why would you expect otherwise? You have said the following: "create a pointer to a memory location (which happens to be where the variable "a" is stored. Put into that location the value held by the variable "b". Since b is 2, the value of a after that operation is 2.
 
  • Like
Likes 1 person
  • #3
so ptr points to vairable a by virtue of ptr=&a and now you've changed a's value to 2 by virtue of *ptr = b where b=2

THe *ptr says store a value in the location where the ptr points which is variable a :

*ptr=b ---equivalent to----> a=b;
 
  • Like
Likes 1 person
  • #4
well, I just wonder what's the difference between the statements *ptr=b and ptr=b.
I thought *ptr=b also means pointer(address)=b because *ptr is still a pointer that stores the address of a.

Then, what's the mechanism? ptr is still pointing at a(stores the address of a).
just copy the value of b that *ptr points to?
 
  • #5
[strike]These two are equivalent: ptr = b, ptr = &b. C will automatically cast to a pointer type if the r-value is not a pointer type. And *ptr = b as explained above is the same as a = b, the type on the left is something like int&, reference to int.[/strike]

[strike]If you think of C++ references like "int &a = b", it's similar to that.[/strike] (see D H's reply)
 
Last edited:
  • #6
verty said:
These two are equivalent: ptr = b, ptr = &b. C will automatically cast to a pointer type if the r-value is not a pointer type.

This is completely wrong. Consider the following:
Code:
#include <stdio.h>
 
int main()
{
   int *ptr;
   int b=2;
 
   ptr = b;
   printf("%p\n", ptr);
 
   ptr = &b; 
   printf("%p\n", &b);
 
   return 0;
}
Demonstration at https://ideone.com/mU7XmC

ptr=b tries to do just what the programmer said to do, which is to set the contents of ptr to the contents of b. With most compilers this statement will result in a warning such as "incompatible integer to pointer conversion". But the compiler does try to do what the programmer said to do, even if it doesn't make much sense.

ptr=&b does exactly what the programmer said to do, which is to set the contents of ptr to the address of b.
 
  • #7
D H said:
This is completely wrong. Consider the following:
Code:
#include <stdio.h>
 
int main()
{
   int *ptr;
   int b=2;
 
   ptr = b;
   printf("%p\n", ptr);
 
   ptr = &b; 
   printf("%p\n", &b);
 
   return 0;
}
Demonstration at https://ideone.com/mU7XmC

ptr=b tries to do just what the programmer said to do, which is to set the contents of ptr to the contents of b. With most compilers this statement will result in a warning such as "incompatible integer to pointer conversion". But the compiler does try to do what the programmer said to do, even if it doesn't make much sense.

ptr=&b does exactly what the programmer said to do, which is to set the contents of ptr to the address of b.

For some reason I remembered that C converts to pointer types automatically, but it seems it is only for arrays that that happens, an array will convert to a pointer to the first element:

Code:
int a[10], *ptr;
ptr = a;
ptr = &a;

The first assignment converts ##a## to a pointer to the first element automatically. The second assignment warns about assignment from incompatible pointer type, I'm not entirely sure why though, the value assigned to ptr is exactly the same. This is just crazy, if one should use ptr = &b, surely one should use ptr = &a when a is an array.

Then also, I tried your example in GCC, it does warn about ptr = b but there is no way to turn that warning into an error without turning all warnings into errors. So probably the answer is to use some kind of lint tool to scan one's code for this type of issue.
 
Last edited:
  • #8
verty said:
For some reason I remembered that C converts to pointer types automatically, but it seems it is only for arrays that that happens, an array will convert to a pointer to the first element:

Code:
int a[10], *ptr;
ptr = a;
ptr = &a;
The first assignment converts ##a## to a pointer to the first element automatically. The second assignment warns about assignment from incompatible pointer type, I'm not entirely sure why though, the value assigned to ptr is exactly the same. This is just crazy, if one should use ptr = &b, surely one should use ptr = &a when a is an array.
Surely not!

The assignment ptr=&b (presumably b is an int rather than an array) instructs the compiler to take the address of b and assign the result to ptr. This is syntactically correct in C and in C++. Both the left and right hand sides are of type pointer to an int. The same is true for the assignment ptr=&a[0].

The assignment ptr=&a (where a is an integer array of ten elements) instructs the compiler to take the address of a and assign the result to ptr. This results in a warning in C and an error in C++. The right hand side is of type int(*)[10] while the target is of type int*. C explicitly allows automatic conversion between different type pointers. C++ does not. It tries to be type safe. The following is legal and compiles without warning in both C and C++:
Code:
int a[10], (*a_ptr)[10];
a_ptr = &a;

What about the assignment ptr=a? This is legal and compiles warning-free in both C and C++. This is because the use of the array a on the right hand side degrades to a pointer.

This degradation of arrays to pointers can be a bit of a nuisance. It hearkens back to the original C, well before there was an ANSI standard, when stack space was a very precious resource. Having arrays degrade to pointers made passing arrays efficient. The degradation to a pointer means that the array access operator (open/close square brackets) is just semantic sugar for pointer dereference. int b = a[4] means exactly the same thing as int b = *(a+4). It also means that one way to obfuscate C and C++ code is to use int b = 4[a].
 

FAQ: Why Does Changing Pointer Assignments in C Affect Variable Values?

What is a pointer in the C language?

A pointer in the C language is a variable that holds the memory address of another variable. It allows for more efficient memory management and manipulation of data.

How do you declare a pointer in C?

To declare a pointer in C, you use the asterisk symbol (*) before the name of the variable. For example:
int *ptr; // declares a pointer to an integer
char *str; // declares a pointer to a character

How do you assign a value to a pointer?

To assign a value to a pointer, you use the ampersand symbol (&) before the name of the variable you want to assign. For example:
int num = 10;
int *ptr = # // assigns the memory address of num to ptr

How do you dereference a pointer in C?

To dereference a pointer in C means to access the value stored at the memory address pointed to by the pointer. This is done using the asterisk symbol (*) before the pointer variable name. For example:
int *ptr = # // assigns the memory address of num to ptr
cout << *ptr; // dereferences ptr to access the value stored at that memory address

How do you free memory allocated to a pointer in C?

In order to free memory allocated to a pointer in C, you use the free() function. This function takes in the pointer variable as its argument and releases the memory allocated to it. It is important to free memory after it is no longer needed to avoid memory leaks.

Similar threads

Replies
19
Views
3K
Replies
1
Views
1K
Replies
4
Views
3K
Replies
2
Views
11K
Replies
19
Views
4K
Replies
2
Views
2K
Replies
6
Views
6K
Replies
7
Views
3K
Back
Top