Here I'm using two string
char str[5], rev[5];
Initially I was trying to performe reverse of a string and it was successful.
While I'm printing the characters of rev
string I mistakenly exceed the limit of string, but still string rev
printing the characters of it.
First I accessed 6 elements from string, in that last element was
blank . This is OKAY because last character having '\0'.
But when I try to access more than 6 elements it's printing the character which are belong to given string ( in my case it is rev
) and some are characters.
This is my code
#include <stdio.h>
int main()
{
char str[5] = "Hello";
char rev[5];
int i = -1, j = 0;
while(str[ i] != '\0');
while(i >= 0)
{
rev[j ] = str[--i];
}
printf("\n i = %d ", i);
printf("\n j = %d \n\n ", j);
rev[--j] = '\0';
printf("%s is reversed string \n ", rev);
for(int k = -5; k <= 15; k )
{
printf("\n k --> %d = ,", k, rev[k]);
}
return 0;
}
I don't understand how this working
$ ./a
i = -1
j = 6
olleH is reversed string
k --> -5 = �
k --> -4 = �
k --> -3 = �
k --> -2 =
k --> -1 =
k --> 0 = o <- Here is the starting point
k --> 1 = l
k --> 2 = l
k --> 3 = e
k --> 4 = H
k --> 5 =
k --> 6 = e <--|
k --> 7 = l <--| From where it comes
k --> 8 = l <--| And how
k --> 9 = o <--|
k --> 10 =
k --> 11 =
k --> 12 =
k --> 13 =
k --> 14 = H <--| This one as well
k --> 15 = �
May be this questios sounds weird**.**
CodePudding user response:
Well it is weird :-) You are abusing your code by accessing arrays with negative indexes, which is not a safe things to do. The biggest problem is that you only reserve 5 chars for the Hello string, but you should put at least 6, factoring the \0 terminator char. It all goes downhill from here
When you do things like these, many factors interact, including the compiler, the operating system and more. So, in my case the program gives a different output.
i = -1
j = 9
�olleH is reversed string
k --> -5 = H
k --> -4 = e
k --> -3 = l
k --> -2 = l
k --> -1 = o
k --> 0 =
k --> 1 = �
k --> 2 =
k --> 3 = o
k --> 4 = l
k --> 5 = l
k --> 6 = e
k --> 7 = H
k --> 8 =
k --> 9 = �
k --> 10 = �
k --> 11 = /
k --> 12 = �
k --> 13 =
k --> 14 =
*** stack smashing detected ***: ./a.out terminated
k --> 15 =
O
CodePudding user response:
The array str
does not contain a string. Its initialization
char str[5] = "Hello";
is equivalent to
char str[5] = { 'H', 'e', 'l', 'l', 'o' };
That is the array str
does not contain the terminating zero character '\0'
.
So starting from this while loop
while(str[ i] != '\0');
the program invokes undefined behavior.
Also in the next loop
while(i >= 0)
{
rev[j ] = str[--i];
}
there is used the expression str[-1]
when i
is equal to 0
that also invokes undefined behavior.
You could declare the arrays for example the following way
char str[] = "Hello";
char rev[sizeof( str )];
And substitute this statement
rev[--j] = '\0';
for this one
rev[j] = '\0';
Also this loop
for(int k = -5; k <= 15; k )
{
printf("\n k --> %d = ,", k, rev[k]);
}
does not make a sense because there are attempts to access memory beyond the defined array. Remove it.
Here is your updated program.
#include <stdio.h>
int main( void )
{
char str[] = "Hello";
char rev[sizeof( str )];
size_t i = 0;
while ( str[i] != '\0' ) i ;
size_t j = 0;
while ( i != 0 )
{
rev[j ] = str[--i];
}
printf( "i = %zu\n", i );
printf( "j = %zu\n\n", j );
rev[j] = '\0';
printf( "%s is reversed string\n ", rev );
return 0;
}
The program output is
i = 0
j = 5
olleH is reversed string