How do I determine the size of my array in C?
Solution 1:
Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide the total size of the array by the size of the array element. You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a
changed you would have a nasty bug if you forgot to change
the sizeof(int)
as well.
So the preferred divisor is sizeof(a[0])
or the equivalent sizeof(*a)
, the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
Solution 2:
The sizeof
way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof
will return the pointer's size, instead of the array's.
Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size
indicating the number of elements in the array.
Test:
#include <stdio.h>
#include <stdlib.h>
void printSizeOf(int intArray[]);
void printLength(int intArray[]);
int main(int argc, char* argv[])
{
int array[] = { 0, 1, 2, 3, 4, 5, 6 };
printf("sizeof of array: %d\n", (int) sizeof(array));
printSizeOf(array);
printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
printLength(array);
}
void printSizeOf(int intArray[])
{
printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}
void printLength(int intArray[])
{
printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}
Output (in a 64-bit Linux OS):
sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2
Output (in a 32-bit windows OS):
sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
Solution 3:
It is worth noting that sizeof
doesn't help when dealing with an array value that has decayed to a pointer: even though it points to the start of an array, to the compiler it is the same as a pointer to a single element of that array. A pointer does not "remember" anything else about the array that was used to initialize it.
int a[10];
int* p = a;
assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));
Solution 4:
The sizeof
"trick" is the best way I know, with one small but (to me, this being a major pet peeve) important change in the use of parenthesis.
As the Wikipedia entry makes clear, C's sizeof
is not a function; it's an operator. Thus, it does not require parenthesis around its argument, unless the argument is a type name. This is easy to remember, since it makes the argument look like a cast expression, which also uses parenthesis.
So: If you have the following:
int myArray[10];
You can find the number of elements with code like this:
size_t n = sizeof myArray / sizeof *myArray;
That, to me, reads a lot easier than the alternative with parenthesis. I also favor use of the asterisk in the right-hand part of the division, since it's more concise than indexing.
Of course, this is all compile-time too, so there's no need to worry about the division affecting the performance of the program. So use this form wherever you can.
It is always best to use sizeof
on an actual object when you have one, rather than on a type, since then you don't need to worry about making an error and stating the wrong type.
For instance, say you have a function that outputs some data as a stream of bytes, for instance across a network. Let's call the function send()
, and make it take as arguments a pointer to the object to send, and the number of bytes in the object. So, the prototype becomes:
void send(const void *object, size_t size);
And then you need to send an integer, so you code it up like this:
int foo = 4711;
send(&foo, sizeof (int));
Now, you've introduced a subtle way of shooting yourself in the foot, by specifying the type of foo
in two places. If one changes but the other doesn't, the code breaks. Thus, always do it like this:
send(&foo, sizeof foo);
Now you're protected. Sure, you duplicate the name of the variable, but that has a high probability of breaking in a way the compiler can detect, if you change it.
Solution 5:
int size = (&arr)[1] - arr;
Check out this link for explanation