Reputation: 8976
Consider this code.
int main()
{
char *s, *t;
s = malloc(4 * sizeof(char));
strcpy(s, "foo");
t = s;
printf("%s %s\n", s, t); // Output --> foo foo
strcpy(s, "bar"); // s = "bar"
printf("%s %s\n", s, t); // Output --> bar bar
}
There are 2 strings s
and t
. First I set s
to "foo"
and then make t
point to s
. When I print the strings, I get foo foo
.
Then, copy "bar"
tos
and print again, I get bar bar
.
Why does value of t
changes in this case? (I copied "bar"
to s
why did t
change).
Now when I change strcpy(s, "bar")
to s = "bar"
-
int main()
{
char *s, *t;
s = malloc(4 * sizeof(char));
strcpy(s, "foo");
t = s;
printf("%s %s\n", s, t); // Output --> foo foo
s = "bar"
printf("%s %s\n", s, t); // Output --> bar foo
}
This code gives me foo foo
and bar foo
.
Why didn't it change in this case?
Upvotes: 3
Views: 300
Reputation: 908
a simplistic way to understand could be as follows :-
s = malloc(4 * sizeof(char)); // this will be interpreted as follows
s = 123 ------------>| | | | | //some garbage values at these location
123 124 125 126 // some random address chosen.
strcpy(s, "foo") ; // it copies at the address provided by s i.e.
|'f'|'o'|'o'|'\0'|
123 124 125 126
t = s; this statement means t it pointing to address = 123
strcpy(s, "bar"); // this statement copies at given address it means it will override previous value . i.e
|'b'|'a'|'r'|'\0'|
123 124 125 126
now t still pointing to address 123 that is why t, s both prints bar .
s = "bar" // this will assign a new address to s which is base address of "bar" string . i.e .
|'b'|'a'|'r'|'\0'|
321 322 323 324
now s will contain address 321 while t has value 123 that is why s and t are giving different values .
Upvotes: 2
Reputation: 121971
This is undefined behaviour, which means anything can happen:
char *s, *t;
strcpy(s, "foo");
as strcpy()
is writing to a random location in memory because s
is an uninitialised pointer.
(after edit that corrected undefined behaviour)
Question 1 - Why does value of t changes in this case? (I copied "bar" to s why did t change).
This is a pointer assignment:
t = s;
and results in both t
and s
pointing to the same memory that was malloc()
and assigned to s
earlier. Any change to that memory is visible via both t
and s
.
Question 2 - Why isn't t changing in the second case?
This assigns the address of the string literal "bar"
to s
:
s = "bar";
so now t
and s
do not point to the same memory location. t
points to the memory that was earlier malloc()
and assigned to s
(because of the t = s;
pointer assignment).
strcpy()
and =
are very different:
strcpy()
copies characters to the memory address specified by its first argument=
, changes the address which a pointer holdsUpvotes: 12
Reputation: 5239
strcpy(s, "foo");
Copies foo
to memory location pointed to by s
t = s;
Now, t
and s
both point to same location
Hence, same output
Now, you copy bar
to s
. Since both t
and s
point to same location. Hence, same output again.
Upto this line everything is same
s = "bar"
You create a string constant bar
. And assign its address to s
. Its a pointer
it can point to any memory location. not necessarily the original one.
Now,
s
points to bar
and t
still to the earlier location it pointed to in the beginning and hence the output
Upvotes: 2