Code:
#include <stdio.h>
int main() {
char *str;
char i = 'a';
str = &i;
str = "Hello";
printf("%s, %c, %x, %x", str, i, str, &i);
return 0;
}
I get this output:
Hello, a, 403064, 28ff0b
I have following two doubts:
How can I store a string without allocating any memory for it.
str
is a character pointer and is pointing to where char variablei
. When I addstr = "Hello";
aren't I using5
bytes from that location4
of which are not allocated?Since, I code
str = &i;
shouldn'tstr
and&i
have same value when I printf them? When I remove thestr = "Hello";
statementstr
and&i
are same. And ifstr
and&i
are same then I believe when I saystr = "Hello"
it should overwrite'a'
with'H'
and the rest'ello\0'
come into the subsequent bytes.I believe the whole problem is with
str = "Hello"
statement. It doesn't seem to be working like what I think.
Please someone explain how it works??
Okay, simply put, every string is a pointer in C.
If we run with this:
When you set
str = &i
, you are makingstr
point toi
. Thus,i == *str
and&i == str
hold true.When you call
str = "Hello";
,str
now points to a statically allocated array of size 6 (this usually resides directly in your program code). Becausestr
is a pointer, when you reset it to point to the new array, it makes no change toi
. Now, if instead of settingstr
to"Hello"
, we did*str = 'Z';
,i
would now have the value of 'Z', whilestr
still points toi
.The literal string
"Hello"
is taking 6 bytes of memory somewhere, probably in the program space. Assigning the pointer to it just sets the pointer to where the string already exists. It doesn't copy the characters at all.If you wanted to copy the characters you would need to use
strcpy
, but as you did not set the pointer to a writable buffer of sufficient size it would cause undefined behavior if you did.No. The compiler sets aside 6 bytes (remember the null terminator) in a different part of memory (a read-only part, but that's an answer to a different question). The assignment:
causes
str
to point to the location of the first of these 6 bytes, theH
.Yes, but you set
str
to point to something else on the very next line, before you printed anything.The memory for the string is allocated by the compiler. I don't think the standard specifies exactly how the compiler must do this. If you run 'strings' against your executable, you should find "Hello" in there somewhere.
I think what you are missing here is that str = "Hello" does not copy the string to the location pointed to by str. It changes what str points to. "Hello" is in memory and you are assigning that memory location to the pointer. If you want to copy memory to a pointer, you need to use memcpy() or something similar.
When the compiler encounters a string literal, in this case
"Hello"
, memory is allocated in the static (global) memory area. This "allocation" is done before your program executes.When your program starts executing at
main
, a stack frame is allocated to store the local variables ofmain
:str
andi
. Note thatstr
is a simple variable that just stores an address. It does not store any characters. It just stores a pointer.The statement
str = &i;
writes into variablestr
the address ofi
.The statement
str = "Hello"
writes into the variablestr
, the address of the string literal"Hello"
which has been pre-allocated by the compiler. This is a completely different address than that ofi
. That assignment does not move any of the characters in the word "Hello" anywhere at all.TL;DR the value of a "string" variable in C is just a pointer. Assigning to a string variable is assigning a number, namely an address.
str
is a pointer to a char. When you saystr = &i;
you are pointing it to an int. When you saystr = "Hello";
you are changing str to point to a location where the character sequence 'H', 'e', 'l', 'l', 'o', 0 is stored.But you say
str = something else
right after you saystr = &i
Looks like you haven't quite grasped pointers yet...