Jytug
Jytug

Reputation: 1116

Getting length of an array

I've been wondering how to get the number of elements of an array. Somewhere in this website I found an answer which told me to declare the following macro:

#define NELEMS(x) (sizeof(x) / sizeof(x[0]))

It works well for arrays defined as:

type arr[];

but not for the following:

type *arr = (type) malloc(32*sizeof(type));

it returns 1 in that case (it's supposed to return 32). I would appreciate some hint on that

Upvotes: 0

Views: 68

Answers (4)

user2959757
user2959757

Reputation: 32

There is no safe and sound way of finding the length of an array in C since no bookkeeping is done for them.

You will need to use some other data structures which does the book keeping for you in order to ensure the correct result every time.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

Pointers do not keep information about whether they point to a single element or the first element of an array

So if you have a statement like this

type *arr = (type) malloc(32*sizeof(type));

then here is arr is not an array. It is a pointer to the beginning of the dynamically allocated memory extent.

Or even if you have the following declarations

type arr[10];
type *p = arr;

then again the pointer knows nothing about whether it points to a single object or the first element of an array. You can in any time write for example

type obj;
p = &obj;

So when you deal with pointers that point to first elements of arrays you have to keep somewhere (in some other variable) the actual size of the referenced array.

As for arrays themselves then indeed you may use expression

sizeof( arr ) / sizeof( *arr )

or

sizeof( arr ) / sizeof( arr[0] )

But arrays are not pointers though very often they are converted to pojnters to their first elements with rare exceptions. And the sizeof operator is one such exception. Arrays used in sizeof operator are not converted to pointers to their first elements.

Upvotes: 2

user3629249
user3629249

Reputation: 16540

And remove the cast. You should not cast the result of malloc and family.

These are the main reasons for not casting the returned value from malloc (and family of functions).

in C, the return type of those functions is 'void*'. A void * can be assigned to any pointer type.

During debugging and during maintenance the receiving pointer type is often changed. The origin of that change is often not where the malloc function is called. If the returned value is cast, then a bug is introduced to the code. This kind of bug can be very difficult to find.

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134386

sizeof operator produces the size of a type of the variable. It does not count the amount of memory allocated to a pointer (representing the array).

To elaborate,

  • in case of type arr[32];, sizeof (arr) is essentially sizeof(type[32]).
  • in case of type *arr;, sizeof(arr) is essentially sizeof(type*)

To get the length of a string, you need to use strlen().

Remember, the definition of string is a null-terminated character array.


That said, in your code,

 type *arr = (type) malloc(32*sizeof(type));

is very wrong. To avoid this kind of error, we suggest do not cast malloc().

Upvotes: 1

Related Questions