1

Ok, so I'm learning pointers and I am having trouble understanding how the pointers function in arrays.

Basically given this:

int a[5] = {1,2,4,7,7}; // (allocated at 0xA000)    
int b[5] = {4,3,5,1,8}; // (at 0xA0020)    
short *c[2];            // (at 0xA0040)
c[0] = (short *)b;
c[1] = (short *)a;

I'm supposed to determine the values of these calculations.

c[0] + 4 

To my understanding c is an array of pointers. c[0] is a short that holds the pointer to the first element of the array b. If b starts at 0xA0020 why is is that c[0] + 4 is not 0xA0024 and instead it is 0xA0028.

Also, how am I supposed to determine the value of c[1][2]. c is not a multidimensional array, so how would this calculation work out?

Thank you!

max
  • 1,509
  • 1
  • 19
  • 24
user2827048
  • 539
  • 6
  • 18
  • Use C[] array of int pointer as int *c[2]; don't be confuse, sizeod short is hlf of size of int on your system. – Grijesh Chauhan Oct 11 '13 at 06:09
  • Please clarify what system this is for. Since this will be another what-happens-when-I-invoke-undefined-behavior guessing contest, we need to know the size of int and short, and the endianess of the CPU. – Lundin Oct 11 '13 at 06:21
  • This topic might help you [How-to-increment-a-pointer-address-and-pointers-value](http://stackoverflow.com/questions/8208021/how-to-increment-a-pointer-address-and-pointers-value/19311446#19311446) This one is taken from stack-overflow itself. I hope it helps. Thank you very much. – vkulkarni Oct 11 '13 at 06:20

6 Answers6

5

Actually, when you add a number to a pointer, this number is multiplied by the size of the element being pointed to (short in your case because you have a short*). The size of short is probably 2 bytes on your computer, hence it adds 4*2 to the address, which is 8.

Here is a link from MSDN that explains this concept:

Click Here

  • 1
    `c[0]` is `short *` not `short`. – Rohan Oct 11 '13 at 06:06
  • @Rohan Exactly, he is adding 4 to a short*, which moves 4 shorts ahead in memory (even though in his case the memory points to ints) –  Oct 11 '13 at 06:07
2

To my understanding c is an array of pointers.

Correct, to be precise: array of pointers to short

C[0] is a short that holds the pointer to the first element of the array b. If B starts at 0xA0020 why is is that c[0] + 4 is not 0xA0024 and instead it is A0028.

Nope, C[0] is a pointer to short. short size is 2 bytes. When you add an integer to pointer, you're adding its pointed type. In this case, since C[0] is a pointer to short, C[0] + 4 means C[0] + 4 * 2 in bytes. So, if C[0] points to 0xA0020, C[0] + 4 will point to 0xA0028.

Also, how am I supposed to determine the value of c[1][2]. C is not a multidimensional array, so how would this calculation work out?

Pointer semantic in C enables you to treat pointer as array. Provided this declaration:

int* X;

Then these equation applies:

      *X == X[0]
*(X + 1) == X[1]

or in general:

*(X + n) == X[n]

where n is an integer value.

Your C is an array of pointers, so first dimension would list the pointers, and second dimension is the data pointed by pointer in the first dimension. Use above equation to find the answer to your question.

NOTE: One thing you have to be aware of is the endianness of the machine. Little endian and big endian stores values bigger than a byte (short, long, int, long long, etc.) in different byte order.

LeleDumbo
  • 9,192
  • 4
  • 24
  • 38
1

This is because the size of a short integer is 2 bytes.

When you do c[0] +4, you're saying, "move forward 4 full spaces from c", where a 'space' is the size of the type c points to (a short, so 2 bytes).

If c were a char*, the result WOULD be A0024 (because a char is 1 byte in size). If it were a long, you'd get A0030 or even more instead-- and so on.

SoItBegins
  • 414
  • 1
  • 6
  • 22
1

c[0] isn't a short that holds a pointer. But rather it's a pointer to a short. And the increment is based on size of what it points to. Which it looks like others have just explained.

KayakDave
  • 24,636
  • 3
  • 65
  • 68
1

In your case c[1][2] gives you a following:
"c" - array of pointers to short (as per declaration in you code)
[1] - gives a second element of array of pointers "c" (pointer to array of integers a)
[2] - gives a data (short) at offset of sizeof(short)*2 from the address of element 2 of array "c" (from start of array "a")
So it will be a one half of second element of array "a". What part you get depends on endianness of your machine.
If you have little endian - then you get a 16 lsb bits of second element of "a". It is 0x0002 in hex, or just "2"

Michael
  • 1,505
  • 14
  • 26
1

(short *)b; is strictly speaking undefined behavior, anything can happen. So the correct answer to what c[0]+4 holds is anything.

Also, even though a specific compiler may implement this undefined behavior in a particular deterministic way, there would still be no way to tell with the information given. To answer, you would have to know the size of int and short, as well as the endianess of the particular machine.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • If `_Alignof(int)` is a multiple of `_Alignof(short)` then the cast is not undefined behaviour. Technically the standard doesn't guarantee that alignment relationship but I doubt any implementation, past present or future, would not have that property – M.M Jan 22 '18 at 12:04
  • @M.M Even if that's true, there's still the issue that the resulting pointer cannot be used for anything meaningful, since it cannot be used to access the data. Doing so would mean a strict aliasing violation. – Lundin Jan 22 '18 at 12:12