Reputation: 87
so here is the code, till the 4th print out I easily followed it, but at the 5th print out, I don't understand
why its "5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302 "
?
I have commented the line in the code which I don't understand. I look forward to your response.
"#include <stdio.h>
#include <stdlib.h>
void
f(void)
{
int a[4];
int *b = malloc(16);
int *c = 0;
int i;
printf("1: a = %p, b = %p, c = %p\n", a, b, c);
c = a;
for (i = 0; i < 4; i++)
a[i] = 100 + i;
c[0] = 200;
printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c[1] = 300;
*(c + 2) = 301;
3[c] = 302;
printf("3: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
c = c + 1;
*c = 400;
printf("4: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
//I DONT UNDERSTAND WHAT THIS LINE BELOW DOES
c = (int *) ((char *) c + 1);
*c = 500;
printf("5: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n",
a[0], a[1], a[2], a[3]);
b = (int *) a + 1;
c = (int *) ((char *) a + 1);
printf("6: a = %p, b = %p, c = %p\n", a, b, c);
}
int
main(int ac, char **av)
{
f();
return 0;
}
output:
1: a = 0x7fff65fdcb90, b = 0x1065007e0, c = 0x0
2: a[0] = 200, a[1] = 101, a[2] = 102, a[3] = 103
3: a[0] = 200, a[1] = 300, a[2] = 301, a[3] = 302
4: a[0] = 200, a[1] = 400, a[2] = 301, a[3] = 302
5: a[0] = 200, a[1] = 128144, a[2] = 256, a[3] = 302
6: a = 0x7fff65fdcb90, b = 0x7fff65fdcb94, c = 0x7fff65fdcb91
Upvotes: 0
Views: 1663
Reputation: 5796
Let's start with the basics.
c
is a pointer to an array of int
s.
Let this be a
:
[00000000][00000000][00000000][00000000]
Every two digits is a byte, and we assume that sizeof(int)
is 4 in our example, so every element in a
has 4 bytes, or 8 digits.
Now, c
is a pointer to the first element in a
.
Let's have a look at the expression in question:
c = (int *) ((char *) c + 1);
Obviously, c
is changed here, but what exactly happens is:
c
is cast from int*
to char*
sizeof(char)
being added to c
. Since sizeof(char)
is 1
, c
is incremented by 1 and points to the second byte of an element in a
.int*
, and reassigned to c
. This second cast is actually not needed.So, ignoring all the other code, we start from this:
a : [00000000][00000000]...
^
c -|
And go to this:
a : [00000000][00000000]...
^
c ---|
As Daniel pointed out below, if c is not correctly aligned for a pointer of type int*
, you get undefined behaviour, which should be avoided.
Upvotes: 9
Reputation: 46667
c
is a pointer-to-int, so normally c+1
refers to the address which is sizeof(int)
further along in memory - usually 4 bytes on a 32-bit system.
But you cast c
to char*
- that is, pointer-to-char. Now, char
is only 1 byte long, so (char *)c + 1
refers to the memory location 1 byte further on than c
; which is in the middle of the int
at c
.
You then cast the result back to an int*
and write 500 into it. So what you're doing is (probably) writing the 4-byte representation of 500 over the last 3 bytes of a[1]
and the 1st byte of a[2]
. Exactly what effect that will have depends on the endianness of your system, but that's basically what's going on.
Upvotes: 3