Reputation: 830
Hi I got confused to get the explanation for this below, can anyone explain it to me? Thanks in advance.
#include<stdio.h>
int main(){
char *arr,c;
arr = &c;
arr++;
*arr = 'a';
arr++;
*arr = 'b';
arr++;
*arr = 'c';
arr--;
arr--;
printf("\narr 1 = %c",arr);
printf("\narr 2 = %c",arr[1]);
printf("\narr 3 = %c",arr[2]);
getch();
return 1;
}
Output is :
arr 1 = a
arr 2 = b
arr 3 = c
but if the change the line:
printf("\narr 1 = %c",arr);
with
printf("\narr 1 = %c",arr[0]);
Now Output is:
arr 1 =
arr 2 = b
arr 3 = c
why 'a' is not getting printed.?
*For all those who are questioning the program as bad coding.. I know its not a good coding practice to use pointer like this, But my question is why arr[0] is not printing anything where as arr[1] & arr[2] is printing what is assigned?
Upvotes: 1
Views: 1293
Reputation: 222941
In the first version of the program, what likely happens is:
c
at some address on the the stack, say 1003 (a single byte).arr
at some address on the stack, say 1004-1007 (four bytes).arr = &c;
puts the address of c
, 1003, into arr
.arr++;
adds one to arr
, so it is now 1004 instead of 1003.*arr = 'a';
writes 'a'
to the place where arr
points. This is now behavior that is undefined by the C standard. When arr
was set to &c
, there was only one byte in the object at that location, and the C standard does not guarantee what happens when you write to other locations after incrementing that address outside the object.arr
, so you are writing 'a'
into one of the bytes of arr
. This horribly alters the address that was in arr
.arr++;
increments the address again, and *arr = 'b';
writes 'b'
somewhere. We do not know where, because arr
has a bad value in it.arr++;
increments the address again, and *arr = 'c';
writes 'c'
somewhere. We do not know where.arr--;
and arr--;
return the address to the value it had after 'a'
was written.printf
call passes the value in arr
to be printed with a “%c” specifier. “%c” is for printing a character, but the arr
you pass it is a pointer. However, you previously wrote 'a'
into the pointer, so the value of the pointer has 'a'
in one of its bytes.printf
prints one of the bytes in the pointer value, in this case the same byte where you wrote 'a'
. So “a” is printed. You cannot rely on this happening in other C implementations. This happened in this case only because the compiler happened to place arr
in memory just after c
in memory, so the statement *arr = 'a';
wrote 'a'
into arr
. This will not happen in all C implementations. You got “lucky.”'a'
into arr
, arr
is pointing somewhere, although we do not know where. Let’s call this location x
.arr++;
and *arr = 'b';
wrote 'b'
to the location x+1
.arr++;
and *arr = 'c';
wrote 'c'
to the location x+2
.arr--;
statements returned arr
to point to x
. So arr[1]
is the character at x+1
, which is 'b'
, and arr[2]
is 'c'
. Passing these to printf to be printed with “%c” prints “b” and “c”.In the second version of the program, when arr[0]
is passed to printf
:
arr
is the value that was formed by writing 'a'
into one of its bytes. This is some “random” address, pointing to no location we have controlled. Apparently there is a 0 character there, or some other non-printing character, so, when arr[0]
is passed to printf
, nothing is printed.arr[1]
and arr[2]
print “b” and “c” because the code wrote 'b'
and 'c'
to those locations.Upvotes: 9
Reputation: 258618
This is just undefined behavior - arr++; *arr = 'a';
is illegal because arr
points to a single char
. Anything can happen.
Upvotes: 6
Reputation:
arr
is not equivalent to arr[0]
, since arr[0]
dereferences the array. The correct equivalent would be &arr[0]
.
By the way, what you're doing invokes undefined behavior, since after incrementing arr
, it points to an invalid memory location - originally it points to a single character, so you can't assume there's anything after it.
Upvotes: 6