#Pointer arrays

26 messages · Page 1 of 1 (latest)

somber rune
#

I’ve seen it where someone allocates a memory and can access it like an array. For example they have a pointer P that they’ve allocated space to, why is it that they can access it with P[x]?

velvet minnowBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

timber moon
#

foo[bar] is equivalent to (*(foo + bar)). this means (among other things) that foo[0] and (*foo) are equivalent; and that foo[bar], (*(foo + bar)), (*(bar + foo)), and bar[foo] are equivalent

little garden
#

Because array indexing is just a shortcut to pointer math. array[i] is the same thing as *(array + i). Note that the math inside the parens is pointer math, it says "multiply i by the size of the array type".

#

So say your allocation is int32_t *array = malloc(1024);, that is an allocation of 1024 bytes, but you address it in int32_t sized chunks (32-bits, 4 bytes).

array[0] is the base address of the allocation. array[1] is the base address, plus 32-bits (4 bytes).

#

array[1] is the same thing as *(array + 1) or "give me what is stored at array plus 32-bits (aka plus 4 bytes)"

#

The * is the dereference operator here. Note that array is a pointer variable, it stores a memory address. So when we want to get what is "at" that memory address, we dereference that pointer.

timber moon
#

oh yeah, pointer math is (as far as i know) defined as foo + bar where foo is a pointer is equivalent to (typeof(foo))((uintptr_t)foo + bar * sizeof(typeof(*foo)))

sterile lark
#

No, pointer arithmetic is defined as indexing an array in the standard.

#

If ptr points to the ith element of an array, then ptr + n points to the i+nth element of the array

#

So all you're doing is treating the pointer as if it points to the 0th element of an array. Memory from malloc is blessed to be able to be treated like this

ornate raptor
#

nor does it require that adding 1 and then casting back gets the next byte

timber moon
timber moon
#

i chose size_t because size_t is "the maximum size of an object", which (as i understand it) is the maximum size representable by the useful bits in a pointer

abstract cloak
#

@somber rune to answer your question:

int* x = malloc(sizeof(int) * 10);

this means we allocate sizeof(int) = 2 * 10 bytes.

that's 20 bytes.

x is a pointer that holds the beginning aggress of this memory region.

when you do:

x[idx]

it effectively means get the value at address: (x + (idx * sizeof(int)))

#

so it ends up just being pointer arithmetic.

#

happy to help.

ornate raptor
#

you're meant to use [u]intptr_t for such conversions, if it exists

timber moon
#

i was trying to avoid what Shaharyar just did and provide an informative but technically incorrect answer. typing *(x + (idx * sizeof(int))) into a C program would result in multiplying idx by pow(sizeof(int), 2) in the generated assembly

abstract cloak
timber moon
# abstract cloak corrected my answer, thank you.

in (x + (idx * sizeof(int))), typeof(x) is still int*, and will be treated as such by the pointer arithmetic. you'd have to either cast x itself to char* or uintptr_t to avoid that (i.e. ((char*)x + (idx * sizeof(int)))). not dereferencing the final value does avoid UB, though