I've decided to complicate my life by learning C. Currently I am trying to fully understand pointers.
So far this is what I understand:
#include <stdio.h>
int main() {
char var = 'A';
// Iniialize a pointer variable to the ADDRESS of variable "var"
char *ptr = &var;
printf("%c", var); // Output: 'A'
// Change the VALUE at the memory location of variable "var"
*ptr = 'B';
printf("%c", var); // Output: 'B'
return (0);
}
But then I was looking into re-assigning a string to a variable, and came across this post, where a pointer variable is assigned a value directly.
This is what I am trying to understand:
#include <stdio.h>
int main() {
// Declare a pointer variable
char *ptr;
// Assign a VALUE directly to a memory location???
ptr = "String 1";
printf("%s", ptr); // Output: "String 1"
return (0);
}
Also, if I assign a new string value to ptr
, such as ptr = "String 2";
, and also output the memory location after each assignment, I get a different memory location:
#include <stdio.h>
int main() {
// Declare a pointer variable
char *ptr;
// Assign a VALUE directly to a memory location???
ptr = "String 1";
printf("%s\n", ptr); // Output: "String 1"
printf("%p\n", ptr); // Output: 0000000000404003 <- one memory location
// Assign a new VALUE to the pointer variable
ptr = "String 2";
printf("%s\n", ptr); // Output: "String 2"
printf("%p", ptr); // Output: 000000000040400F <- a new memory location
return (0);
}
Am I really assigning a VALUE to the memory location the pointer variable is referencing?
Why does the memory location change when I assign a new value to the pointer variable?
CodePudding user response:
pointer
hold reference to (address of) the object.
char *ptr = "string 1";
is the same as
char *ptr;
ptr = "string 1";
it assigns the pointer ptr
with the address of the string literal "string 1"
. String literals are null character terminated const char
arrays.
When you :
ptr = "string 2";
you assign the pointer ptr
with the address of another string literal. And as I wrote above is simply a const char
array. Addresses of both string literals are different.
ptr = "String 2"; printf("%s\n", ptr); // Output: "String 1"
It is not possible, and you post here different code than you run on your computer. It will print String 2
for sure.
// Assign a VALUE directly to a memory location??? ptr = "String 1";
No, this assignment only assigns pointer ptr
with the address of string literal which resides somewhere in memory. It does not allocate the space or copy this string anywhere.
The magic *
:
When you use the dereference operator *
you access the object the pointer is referencing.
char str[] = "String 1";
char *ptr;
ptr = str;
*ptr = 'X';
printf("str = `%s` And its address is %p\n", str, (void *)str);
printf("ptr = `%s` it is holging %p address. Its address is %p\n", ptr, (void *)ptr, (void *)&ptr);
Output:
str = `Xtring 1` And its address is 0x7ffdc9047827
ptr = `Xtring 1` it is holging 0x7ffdc9047827 address. Its address is 0x7ffdc9047818
As you see it changes the first character of the str
as pointer ptr
holds the address of the first character of this array.
https://godbolt.org/z/x8PsW9vsP
CodePudding user response:
To assign a value to an object using a pointer that points to the object you need to dereference the pointer as you are doing in the first your program.
*ptr = 'B';
As for this code snippet
char *ptr;
ptr = "String 1";
then there is declared a pointer that then is assigned with the address of the first character of the string literal "String 1"
.
You can reassign the pointer like
ptr = "String 2";
but this reassigns the pointer itself not the object previously pointed to by the pointer. That is now the pointer points to the first character of the string literal "String 2"
.
Pay attention to that you may not change the string literal using the pointer like for example
*ptr = 's';
Any attempt to change a string literal results in undefined behavior.
But you can change a character array initialized by a string literal like
char s[] = "String 1";
char *ptr = s;
*ptr = 's';