tags:

views:

198

answers:

10

I'm working with C, but I think this is a more low level question that isn't language specific.

How does the program correctly grab the right data with array[0] or array[6] regardless of what type of data it holds? Does it store the length internally or have some sort of delimiter to look for?

A: 

No it doesn't. It just get/set element at address array + X*sizeof(TypeOfArrayEl) so you can easily get out of bounds and no one might give you error at that time. That's why array[6] is same as 6[array]

Andrey
+7  A: 

The compiler figures out the size at compile time and hard-codes the size in the object code.

Jerry Coffin
A: 

Assume array is of type int:

int array[12];

The [] operator adds whatever value is in the brackets (times the size in bytes of the array type) to the value outside the brackets. Arrays are stored by the implementation as pointers to their first items. So that array declaration above allocates 12 * sizeof(int) bytes and makes array point to the first one. This leads to wonky stuff like 3[array] giving you the third element in the array.

Anyway, the answer to your question is that the compiler looks at the type of the array at compile time and multiplies the thing in the [] by the size of the type held by the array.

Nathon
+2  A: 

The compiler substitutes the length of the datatype which is fixed at compile time.

int getInt(void * memory, offset)
{
     return *((int *)(sizeof(int)*offset + memory))
}

void * chunkOfMemory = malloc(0x1000);
int * intarray = (int *) chunkOfMemory;
printf("%d is equal to %d", getInt(chunkOfMemory, 9), intarray[9]);
Novikov
I think you meant to use "chunkOfMemory" on those last two lines.
mouche
indeed, good catch
Novikov
A: 

From what I remember C doesn't give you a compile time error if the index is out of bounds. Even if you go beyond the bounds the pointer simply provides you the next adjacent memory location. The only thing that C takes care of is by how many bytes to increase the pointer. If its an integer array then the pointer will advance by 2 bytes for every increment in the index and for char it'll increment by 1 byte.

You can always access locations that are out of bounds but that is junk data and you as a programmer has to ensure that you're accessing the right data.

That is the price of freedom I guess :)

Sidharth Panwar
No, if it's an integer array, it will advance by `sizeof(int)` "bytes" (chars) for every increment. There is no modern platform on which `sizeof(int)` is 2.
R..
Agreed, I didn't include the sizeof to keep the thing simple. I should've mentioned that if the size of an integer is 2 bytes than the pointer moves by 2 bytes.
Sidharth Panwar
+2  A: 

The compiler knows the size of each element of the array at compile time. For instance:

int64_t array[5];
...
int64_t a = array[3];

This will be converted to the pseudo-assembly code:

addr <- array
addr <- addr + 3 * sizeof(int64_t)
//                 ^^^^^^^^^^^^^^^ which the compiler knows is 8
//             ^^^^^^^^^^^^^^^^^^^ which the compiler can replace with 24.
a <- *addr 

The length of the array doesn't matter.

KennyTM
+1 for showing pseudo-assembly.
Platinum Azure
+1  A: 

It's compiler magic!

The compiler knows the size of the array elements and uses it to calculate the right address.

pmg
+12  A: 

the compiler knows the sizeof the underlying datatype and adds the right byte offset to the pointer.

a[10] is equivalent to *(a + 10) which is equivalent to *(10 + a) which in turn is equivalent to 10[a], no kidding.

Jens Gustedt
Indeed. To delve more thoroughly into this, see http://stackoverflow.com/q/381542
Dinah
it is like magic. the black one...
Sergey Mirvoda
Black magic is fine. So long as it makes sense ;)
Matt Joiner
+5  A: 

Neither :-)

For an array, the compiler knows: (a) the address of the start of the array, and (b) what type of elements (int, float, double, etc.) the array holds, and hence how long each element is.

With those two pieces of information, finding array[6] is a simple matter of arithmetic: start with the base address, and add 6 times the size of an element.

David Gelhar
+6  A: 

I would like to contribute something other than a direct answer.

There is an interesting article on Dennis Ritchie's homepage on the history of C which has quite a bit to say about arrays, array indices, etc.

This will probably not directly answer your question, but it may further your understanding of C arrays... and it is an interesting read.

stakx
+0.5 (rounded up) for the article.
pmg