9

As I continue learning the C language I got a doubt. Which are the differences between using an array in which each element is an struct and using an array in which each element is a pointer to the same type of struct. It seems to me that you can use both equally (Although in the pointers one you have to deal with memory allocation). Can somebody explain me in which case it is better to use one or the other?

Thank you.

3
  • 3
    One example: Using qsort to sort the array-of-pointers may be faster than sorting the array-of-structs (if the struct is very large), since swapping two pointers will be faster than swapping two structs. Commented Feb 19, 2017 at 15:03
  • 3
    ^ OTOH, a sequential pass over the array of structures will be more cache friendly and won't requires an extra indirection at each step. Commented Feb 19, 2017 at 15:05
  • 1
    I don't think this question is too broad: there is some level of personal opinion in the advantages and drawbacks each method has, but the question is a genuine interrogation and listing the relevant features of both solutions seems feasible. Commented Feb 19, 2017 at 15:33

1 Answer 1

12

Arrays of structures and arrays of pointers to structures are different ways to organize memory.

Arrays of structures have these strong points:

  • it is easy to allocate such an array dynamically in one step with struct s *p = calloc(n, sizeof(*p));.
  • if the array is part of an enclosing structure, no separate allocation code is needed at all. The same is true for local and global arrays.
  • the array is a contiguous block of memory, a pointer to the next and previous elements can be easily computed as struct s *prev = p - 1, *next = p + 1;
  • accessing array element members may be faster as they are close in memory, increasing cache efficiency.

They also have disadvantages:

  • the size of the array must be passed explicitly as there is no way to tell from the pointer to the array how many elements it has.
  • the expression p[i].member generates a multiplication, which may be costly on some architectures if the size of the structure is not a power of 2.
  • changing the order of elements is costly as it may involve copying large amounts of memory.

Using an array of pointers has these advantages:

  • the size of the array could be determined by allocating an extra element and setting it to NULL. This convention is used for the argv[] array of command line arguments provided to the main() function.
  • if the above convention is not used, and the number of elements is passed separately, NULL pointer values could be used to specify missing elements.
  • it is easy to change the order of elements by just moving the pointers.
  • multiple elements could be made to point to the same structure.
  • reallocating the array is easier as only the array of pointers needs reallocation, optionally keeping separate length and size counts to minimize reallocations. Incremental allocation is easy too.
  • the expression p[i].member generates a simple shift and an extra memory access, but may be more efficient than the equivalent expression for arrays of structures.

and the following drawbacks:

  • allocating and freeing this indirect array is more cumbersome. An extra loop is required to allocate and/or initialize the structures pointed to by the array.
  • access to structure elements involve an extra memory indirection. Compilers can generate efficient code for this if multiple members are accessed in the same function, but not always.
  • pointers to adjacent structures cannot be derived from a pointer to a given element.

EDIT: As hinted by David Bowling, one can combine some of the advantages of both approaches by allocating an array of structures on one hand and a separate array of pointers pointing to the elements of the first array. This is a handy way to implement a sort order, or even multiple concomitant sort orders with separate arrays of pointers, like database indexes.

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

1 Comment

I would like to note that i've identified the following issue with arrays of structs: it is not clear if elements of such arrays should be accessible by pointers or by references in addition to indices. Allowing such a dual access looks "unclean" (breaking an abstraction barrier, allowing multiple ways to access the same location) and thus bug prone (for example if the array needs to be reallocated). Allowing only access by indices adds an extra indirection and a computation, and makes it tricky to evaluate some function that takes a struct reference on an array item.

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.