I am having a conceptual doubt.
char ch[20]="some string";
I wanted to know how ch is being stored i.e. whether 20 bytes are allocated or just the length of the string assigned to it? Can we access something like ch[18] here?
I am having a conceptual doubt.
char ch[20]="some string";
I wanted to know how ch is being stored i.e. whether 20 bytes are allocated or just the length of the string assigned to it? Can we access something like ch[18] here?
I wanted to know how
ch
is being stored i.e. whether20
bytes are allocated or just the length of the string assigned to it?
It creates an array by name ch
which is 20
characters long and initalizes it with "some string".
Yes, the array is 20 bytes in size.
Can we access something like ch[18] here?
Yes We can. And even modify the contents.
Good Read:
What is the difference between char a[] = “string”; and char *p = “string”;
To answer Q in comment:
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
ch:| s | o | m | e | | s | t | r | i | n | g | \0 | | | b | \0 |
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
0 1 2 3 4 5 6 7 8 9 10 11 12 ...... 18 19
When you do,
ch[18]='b';
The modification has happend only that you cannot see it.
printf
determines the end of string by detecting \0
. The \0
was placed at the end of the string when you initialized it.The rule in C/C++ while declaring an array whenever initializers are given, any uninitialized elements are automatically set to 0. As you see in above the diagram depiction the modified character is placed after what printf
thinks is end of string and hence you cannot see it in output of printf
.
If you output the string each character by a for-loop by iterating over it, You can see your modification.
whether 20 bytes are allocated
Yes, 20 bytes are allocated since you told it to do so. It's just that the first 12 bytes of the array will be initialized using your string and its trailing NUL, the other bytes are padded with zeros. However, you can still access (read and write) all the 20 bytes of the array, i. e. from ch[0]
to ch[19]
.
If you had written
char ch[] = "some string";
then ch
would have been created as a 12-element array:
{ 's', 'o', m', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0 }
and only then would it have been erroneous to attempt to read or write past the bounds of the array, i . e. ch[12]
and higher indices would have invoked undefined behavior.
If you write
char *ch = "some string";
that's really bad and if you need a string literal as a char pointer, you should really write
const char *ch = "some string";
In this case, the ch
pointer points to a 12-byte long string, of which the characters are constant, so they're read-only - attempting to modify them (in addition to reading out of the bounds) is, again, undefined behavior.
20 bytes are allocated to ch
since you declared it to use 20 bytes. yes you Can access ch[18].
The problem with
char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);
is that the literal "some string" is stored including its NULL
terminator, so when you print it the string only prints till the first null terminator.
Yes you can access ch[18], you overallocated the array and the bytes after your constant string will still be there, full of uninitialized data. Look at the memory location.
`how ch is being stored` and `whether 20 bytes are allocated`
20 bytes are allocated actually, and the memory addresses allocated are constant. "ch" here is a pointer to the first byte(or char) of the memory allocated. And "ch+1" points the second byte of the memory allocated.
Can we access something like ch[18] here?
If the length of string is shorter than the memory size you requested(20 in this case), you still get the requested size, and the values in other bytes are not certain(may be 0 or not, but in vc6, it is often intialized as 0). ch[18] can be accessed, but the value may be unknown. So you may have to take the efforts to initialize them to 0 by yourself, if you want to access them.