zoy.khan
zoy.khan

Reputation: 87

How does the int and char pointer affect my print out here?

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

Answers (2)

Andreas Grapentin
Andreas Grapentin

Reputation: 5796

Let's start with the basics.

c is a pointer to an array of ints.

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:

  1. c is cast from int* to char*
  2. the result of the cast is incremented, resulting in 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.
  3. the result is cast back to 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

Chowlett
Chowlett

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

Related Questions