In C, no information about the size of the array is stored with the array. You have to know how big it is to work with it safely.
There are a few techniques for working around this. If the array is declared statically in the current scope, you can determine the size as:
size_t size = (sizeof(a) / sizeof(a[0]);
This is useful if you don't want to have to update the size every time you add an element:
struct point a[] = {{1, 1, 1}, {2, 2, 2}};
size_t size = (sizeof(a) / sizeof(a[0));
But if you have an arbitrary array, that has been passed in from somewhere else, or converted to a pointer as in your example, you'll need some way of determining its size. The usual ways to do this are to pass the size in along with the array (either as a separate parameter, or as a struct containing the array), or if the array is of a type which can contain a sentinel value (a value of the given type that is not valid), you can allocate an array one bigger than you need add a sentinel to the end of the array and use that to determine when you've reached the end.
Here's how you might pass in a length as a separate argument:
struct point myfunction(struct point array[], size_t n) {
for (size_t i = 0; i < n; ++i) {
struct point p = array[i];
// do something with p ...
}
}
Or as a structure containing the length:
struct point_array {
size_t n;
struct point elems[];
}
struct point myfunction(struct point_array a) {
for (size_t i = 0; i < a.n; ++i) {
struct point p = a.elems[i];
// do something with p ...
}
}
It would probably be hard to use sentinel values with an array of struct point
directly, as there is no obvious invalid value that is still of the same type, but they are commonly used for strings (arrays of char
which are terminated by a '\0'
character), and arrays of pointers which are terminated by a null pointer. We can use that with struct point
by storing pointers to our structures rather than storing them inline in the array:
struct point *myfunction(struct point *a[]) {
for (size_t i = 0; a[i] != NULL; ++i) {
struct point *p = a[i];
// do something with p ...
}
}