3

I have this small code:

int* array_int = new int[10];
    array_int[0] = 1;
    array_int[1] = 2;
    array_int[2] = 3;
    array_int[3] = 4;
    array_int[4] = 5;
    array_int[5] = 6;
    array_int[6] = 7;
    array_int[7] = 8;
    array_int[8] = 9;
    array_int[9] = 10;

    print(array_int);
    print(array_int + 1);
    print(array_int + 2);

The output is this:

Address: 009694B0
Value: 1
Address: 009694B4
Value: 2
Address: 009694B8
Value: 3

The address is stored after 4bytes from previous?

So 009694B0 points to the first byte of int 1? So 009694B1 points to the second byte of int 1 and so on?

I thought 009694B0 points to int 1 and 009694B1 to int 2 and so on.

3 Answers 3

2

Arrays need to leave enough space between each offset's address to fit what they're storing. Since you've got an array of 4-byte ints, there's a four byte difference between each element's address.

Let's look at what an array of 4-byte ints looks like in memory (on a byte-addressable big-endian system). I'm going to use some different numbers for the values, so we can easily track which bytes belong to which integers. Here's the array I'm using:

int* array = new int[4]
array[0] = 0x1A1B1C1D
array[1] = 0x2A2B2C2D
array[2] = 0x3A3B3C3D
array[3] = 0x4A4B4C4D

And here's what it looks like in memory:

Address  Byte  Offset  Int
...
009694B0 (1A) -- 0  \
009694B1 (1B)  |     \ 0x1A1B1C1D
009694B2 (1C)  |     /
009694B3 (1D) /     /
009694B4 (2A) -- 1  \
009694B5 (2B)  |     \ 0x2A2B2C2D
009694B6 (2C)  |     /
009694B7 (2D) /     /
009694B8 (3A) -- 2  \
009694B9 (3B)  |     \ 0x3A3B3C3D
009694BA (3C)  |     /
009694BB (3D) /     /
009694BC (4A) -- 3  \
009694BD (4B)  |     \ 0x4A4B4C4D
009694BE (4C)  |     /
009694BF (4D) /     /
...

And here is what it would look like if each value was stored in the next byte, instead of the fourth byte:

Address  Byte  Offset  Int
...
009694B0 (1A) -- 0    0x1A2A3A4A
009694B1 (2A) -- 1    0x2A3A4A4B
009694B2 (3A) -- 2    0x3A4A4B4C
009694B3 (4A) -- 3    0x4A4B4C4D
009694B4 (4B)  |
009694B5 (4C)  |
009694B6 (4D) /
...

That's not quite what we put in. Only the last number we assigned, 0x4A4B4C4D came out unscathed. The rest were partially overwritten by the later numbers.

3
  • This is the representation for a Big-Endian machine. It might be a good idea for you to include the representation for a little-Endian machine, given their ubiquity (cough x86 cough) in the Real World. Jun 3, 2016 at 18:46
  • @JohnR.Strohm I think for this question, the difference between BE and LE is less important than space required and the overwriting that occurs when there isn't enough space. I'm satisfied with the link to Wikipedia's endianness page that I included, and a bit worried that the extra example might be too much noise. But if more people (especially the OP) want to see it I could add it.
    – 8bittree
    Jun 3, 2016 at 19:02
  • thanks for the complete explanation...and yes i'm reading the link right now...can you suggest me some link or book that talks about memory and how does it work in low level? i'm studying c++ and about memory (and how computer physically works) i lack of knowledge
    – tuttomax
    Jun 3, 2016 at 19:07
4

Your int is 32 bits wide, so it needs 4 bytes of storage space. The pointer data type is smart enough to know this, so incrementing it by 1 actually points 4 memory cells farther down the memory, and that's what you see in the output.

5
  • 2
    maybe replace "smart enough" with "required" or "defined"
    – Caleth
    Jun 3, 2016 at 11:06
  • right so simple...i can't figure out how draw that on my paper...but so address between are left empty or are used?
    – tuttomax
    Jun 3, 2016 at 11:06
  • 3
    Address 009694B0 points to the first byte of your integer, which is equivalent to pointing "to the integer". Address 009694B1 points to the second of four bytes that constitute this integer. If you tried to read an int from that pointer, you wouldn't get any of your ten ints, but a value that corresponds to parts of the bit patterns of the first and the second int intermixed. Jun 3, 2016 at 11:24
  • Might be worth mentioning what happens if you cast to a long* or long long* or char* and increment that instead.
    – Ixrec
    Jun 3, 2016 at 12:35
  • @tuttomax: The entire integer occupies four bytes because it takes four bytes to hold it no matter what the value stored there.
    – Blrfl
    Jun 3, 2016 at 19:19
0

The smallest addressable data on modern computers is 1 byte. Sequential addresses are by byte. However, addresses can have a type. In your example, the address has type int *. Each int takes up 4-bytes (on your computer). So incrementing an address of type int * will increment 4 bytes.

Try the experiment again with type char * and then again with type long * to show to yourself how the address increments. You can also use a void * pointer and try incrementing that pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.