1
typedef struct node {
    int value;
    struct node* next;
}node;

int* to_array (node* ll, int size) {
    int i = 0;
    int* arr = malloc(size*sizeof(int));
    while (ll) {
          arr[i] = ll->value;
          ll = ll->next;
          i++;
    }

return arr;
}

Can someone please explain why

int* arr = malloc(size);

will give us an array? I thought when we have pointers we cannot change it individually like arr[i] = 5 or something.

0

3 Answers 3

5

Your is actually a very good question. Granted, one that's already been asked and answered many times on SO. But a good question nonetheless.

From the C/C++ FAQ:

http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr

Arrays are not pointers, though they are closely related (see question 6.3) and can be used similarly (see questions 4.1, 6.8, 6.10, and 6.14).

  1. When you declare an array (e.g. int a[5]), you've allocated storage for five "int" elements. You can access each element like a[i].

  2. When you declare a pointer (e.g. int *b) you haven't allocated ANY storage.

  3. You can declare and initialize a pointer at the same time:

    int *b = NULL;  /* Initialize to 0 */
    ... OR ...
    int *b = malloc (5 * sizeof (int)); /* Allocate storage for 5 "int" elements */
    
  4. When you declared array a, you allocated space from the stack. The allocation cannot be changed.

    When you declared b, you allocated the SAME amount of space, but you allocated from the heap. Further, you can change b to point to anything else, at any time. You can also realloc() your memory to change the size of your storage.

  5. Just as you can use index syntax a[i], you use exactly the same syntax b[i].

This link might help explain: http://www.geeksforgeeks.org/g-fact-5/

PS: When you "have pointers", you most definitely CAN "change it individually like arr[i] = 5 or something".

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I appreciate your detailed explanation! I understand it now.
2

int *arr = malloc(size * sizeof(int)); does not give an array, it gives you a block of memory large enough to hold size integers.

The arr[i] = ll->value; statement uses pointer arithmetic: an expression arr + 5 means take the memory address of the integer pointed to by arr and move 5 positions on from there. Now, because the compiler knows that it is working with int pointers, and assuming 32-bit ints, it will know to add 20 (=5*4bytes) to the value of arr to find the 6th element.

Next, the C language has the syntactic sugar where the expression arr[5] is equivalent to *(arr + 5).

This is also why arrays in C are indexed from 0, and why the name of a C array can also be used as a pointer to the first element of the array.

Comments

1

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;

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.