Array sizeof

Hi ive been looking at some sample code given to me by a friend a long time ago and unfortunately been unable to make sense of one area of it.

He has function which takes two parameters and I don't understand the purpose one of the parameters the function is as outlined below.

void function(unsigned long *array, unsigned int sizeArray);

Now the part I cant make sense of is when he calls the function he calls it like so...

function(array, sizeof(array) / sizeof(array[0]));

what is the purpose of dividing the size of the array by the sizeof the first part and experimenting with this in the IDE on a board using sizeof(array[0]) only ever returns 2 no matter what is in the array or how long it is, so why not just divide by 2?

So what is the purpose of sizeof(array[0]);.

The code is rather long but its for processing infrared marks and spaces i would post more but i would end up posting the whole thing to go any further in detail.

anyone shed some light on this.

Thanks, Shandy.

sizeof returns the number of bytes taken by the given object.

long x [32];
...
...

y = sizeof(x);
z = sizeof (x) / sizeof (x[0]);

Here y has the value 128, and z the value 32, because a long occupies 4 bytes.

Shandy:
what is the purpose of dividing the size of the array by the sizeof the first part and experimenting with this in the IDE on a board using sizeof(array[0]) only ever returns 2 no matter what is in the array or how long it is, so why not just divide by 2?

It makes it portable to other systems. In another environment, it might return 1 or 4, or something else.

So, if you read the two answers above, you may be able to figure out that you can use the division of the size of the entire array object by the size of one element (usually the zeroth) to compute the number of elements in the Array!

This is common and used quite frequently to iterate over the values in the array, making it extensible/accommodating to changes in the count of elements in the Array.

The sizeof operator (it's not actually a function) returns the size of the given element in 8-bit bytes. This is kind of odd on 32-bit systems but it's a consistent measure that doesn't change for any system on any hardware.

This function:void function(unsigned long *array, unsigned int sizeArray);
is really using sizeArray to represent the number of elements in the array. Perhaps it should have been named "numElements" or something. This can be whatever you want because it's your program, not a C language standard.

If sizeof(array[0]) really is returning 2 then you may have other problems. The function definition declares that its using an array of long integers, which are usually 4 bytes on most C systems, including Arduino. This may mean that it will interpret your array incorrectly.

& is the address-of operator. For example, the address of array[0] can be found with the expression &(array[0]) This might return a number like 1001 the actual number is never important unless you are a writing a new C compiler, but I need to use a number for this example. So what is the address of the next element in the array? What is &(array[1])?

It depends on what's in the array. If it's an array of integers, where sizeof(array[0]) equals 2, then &(array[1]) equals 1003. If it's an array of long integers, like the function declaration says it is, then &(array[1]) equals 1005. It can get even more complex if you are on a system with word-aligned memory. So you can see that it's quite important to use the correct declarations or you will be missing parts of your array and maybe even overwriting random parts of memory somewhere else.

MorganS:
The sizeof operator (it's not actually a function) returns the size of the given element in 8-bit bytes.

Isn't it actually 'CHAR_BIT' size chunks?

Where 'CHAR_BIT', defined in the file "limit.h", is architecture dependent.

Well, there are weird systems with 6 bits or 12 bits. I don't think you can run C on any of them.

I would not be surprised to see a 32-bit system with strong alignment that will use 32 bits to store a char. I would expect sizeof(char) to show 4 on such a system.

My point was don't make the assumption, look it up!

You can get both the data and the size of the array of you use a template.( as well as the type of the array i.e. Int, byte, float...)

template<typename T, size_t N>
void someFunction(T (&data)[N] )
{
    for( byte i = 0; i < N; i++)
    { 
        Serial.println(data[ i ]);
    }
}

Now just call it like a regular function, but instead of passing in both the array and array size, you just pass in the array.

MorganS:
I would expect sizeof(char) to show 4 on such a system.

That would be nonstandard.
sizeof(char) = 1

According to my copy of the Standard:

5.3.3 Sizeof

The sizeof operator yields the number of bytes in the object representation of its operand.
...
sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1.
...
Note: See 1.7 for the definition of byte ...

1.7 The C++ memory model

The fundamental storage unit in the C ++ memory model is the byte. A byte is at least large enough to contain any member of the basic execution character set (2.3) and the eight-bit code units of the Unicode UTF-8 encoding form and is composed of a contiguous sequence of bits, the number of which is implementation-defined. The least significant bit is called the low-order bit; the most significant bit is called the high-order bit. The memory available to a C ++ program consists of one or more sequences of contiguous bytes. Every byte has a unique address.

lloyddean:
Isn't it actually 'CHAR_BIT' size chunks?

Where 'CHAR_BIT', defined in the file "limit.h", is architecture dependent.

It's limits.h.

/* Number of bits in a `char'.  */
#undef CHAR_BIT
#define CHAR_BIT __CHAR_BIT__

I'm not sure that is the same as the number of bits in a byte (in the general case). Can you quote a reference?

MorganS:
Well, there are weird systems with 6 bits or 12 bits. I don't think you can run C on any of them.

I would not be surprised to see a 32-bit system with strong alignment that will use 32 bits to store a char. I would expect sizeof(char) to show 4 on such a system.

I would be absolutely amazed if there were any systems left, outside of a history museum, that did not support byte and word addressing. The amount of additional logic is infinitesimal compared to the amount of logic in any modern processor.

Regards,
Ray L.

void function(unsigned long *array, unsigned int sizeArray);

Now the part I cant make sense of is when he calls the function he calls it like so...

function(array, sizeof(array) / sizeof(array[0]));[tt]

[/quote]

In C, arrays "evaluate" to a pointer to their first element. When you pass an array, what actually gets passed is that pointer. This means that the receiver doesn't get info about the length of the array. So it has to be passed either explicitly, by some sort of implicit rule (eg, strings finish with a NUL byte), or by putting it in a struct or other array or something even weirder.

[tt]sizeof(array) / sizeof(array[0])


or the equivalent `sizeof(array) / sizeof(*array)` is the C idiom for getting the number of elements in an array. If I saw this in someone's code: `sizeof(array) / 2`, as a C programmer I'd be wondering why the programmer explicitly divided by 2 in particular, because I'm used to seeing it the other way.