In this statement
int* arr = malloc(size*sizeof(int));
function malloc allocates an extent of memory that is capable to store size objects of type int and returns pointer to this extent (or to the first slot in the extent where an object of type int can be accomodated) as having type void * that is implicitly converted to type int * because in the left side of the declaration identifier arr has type int *.
According to the C Standard (6.5.2.1 Array subscripting)
2 ...The definition of the subscript operator [] is that E1[E2] is
identical to (*((E1)+(E2))). Because of the conversion rules that
apply to the binary + operator, if E1 is an array object
(equivalently, a pointer to the initial element of an array object)
and E2 is an integer, E1[E2] designates the E2-th element of E1
(counting from zero).
Thus this expression
arr[i]
is evaluated like
*( arr + i )
where in the subexpression
arr + i
there is used the pointer arithmetic that is this expression points to i-th element in the allocated extent of memory.
If you have an array declared for example like
int array[size];
then in this expression
array[i]
the array name is implicitly converted to pointer to its first element. You may imagine it like
int *p = array;
*( p + i )
Thus if you have the following declarations
int array[size];
int *p;
then the following statements are equivalent
array[1] = 10;
and
p = array;
*( p + 1 ) = 10;
Becuase operation array + i is commutative then you can write interchangeably
array[i]
and
i[array]
For example in your function you could write
i[arr] = ll->value;
Though it would only confuse readers.:)
Beginners always wonder when see code like this
int a[10];
0[a] = 5;