Using Sizeof on Arrays Passed as Parameters

Using sizeof() on an array passed to a function

Array in C always passed by reference. Thats why you are getting pointer size each time, not actual size.

To work with array in C as an argument, you should pass size of array with array.

I modified your program to working condition:

typedef unsigned char BYTE;

void checkArraySize(BYTE data[], int sizeOfArray)
{
int internalSize = sizeOfArray;
printf("%d", internalSize );
}

void main(void)
{
BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
int externalSize = sizeof(data)/sizeof(BYTE); //it would return number of elements in array

checkArraySize(data, externalSize);
}

passed by reference means only address of first element of array is sent. If you change anything even inside function checkArraySize, this change would be reflected to original array too. Check modified above example.

typedef unsigned char BYTE;

void checkArraySize(BYTE data[])
{
int internalSize = sizeof(data);
printf("%d\n", internalSize );
data[3]= 0x02; //internalSize is reported as 4
}

void main(void)
{
BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
int externalSize = sizeof(data); //externalSize is reported as 8
printf("Value before calling function: 0x%x\n",data[3]);
checkArraySize(data);
printf("Value after calling function: 0x%x\n",data[3]);
}

output would be:

Value before calling function: 0x4
4
Value after calling function: 0x2

Using sizeof on arrays passed as parameters

What causes this inconsistency?

The name of the array decays as an pointer to its first element.

When you pass an array to an function, this decaying takes place and hence the expression passed to sizeof is a pointer thus returning pointer size.

However, an array passed to sizeof always returns size of the array because there is no decaying to an pointer in this case.

What is the best way of getting the size of an array when it is passed as a parameter?

Don't pass them by value, pass them by reference or

Pass size as an separate argument to the function.

Sizeof array passed as parameter of function

In most cases the size of a pointer is 8 bytes. In your system that is the size of the pointer.

Note that the size of the pointer, and you probably know this, is not the size of the object it points or the size of the type of object.

The size of a pointer depends on several factors, like the CPU architecture, compiler or Operating System.

The way it usually works is if the system is 16-bit, the of size pointers is 2 bytes, if the system is 32-bit, the size is 4 bytes, if it is 64-bit, it's 8 bytes.

Find the Size of integer array received as an argument to a function in c

You cannot do it that way. When you pass an array to a function, it decays into a pointer to the first element, at which point knowledge of its size is lost.

If you want to know the size of an array passed to the function, you need to work it out before decay and pass that information with the array, something like:

void function (size_t sz, int *arr) { ... }
:
{
int x[20];
function (sizeof(x)/sizeof(*x), x);
}

Weird behavior of sizeof for arrays passed as parameters

I never saw that syntax before in C++ but maybe you meant

void foo(const char data[10])

Anyway, in C++ arrays decay to pointers when passed to a function. So the function has no way of knowing how big the passed arrays are. In that sense, what I wrote above is completely equivalent to:

void foo(const char data[])

There is also a C FAQ about this subject.

Why isn't the size of an array parameter the same as within main?

An array-type is implicitly converted into pointer type when you pass it in to a function.

So,

void PrintSize(int p_someArray[10]) {
printf("%zu\n", sizeof(p_someArray));
}

and

void PrintSize(int *p_someArray) {
printf("%zu\n", sizeof(p_someArray));
}

are equivalent. So what you get is the value of sizeof(int*)

C sizeof a passed array

There is no magic solution. C is not a reflective language. Objects don't automatically know what they are.

But you have many choices:

  1. Obviously, add a parameter
  2. Wrap the call in a macro and automatically add a parameter
  3. Use a more complex object. Define a structure which contains the dynamic array and also the size of the array. Then, pass the address of the structure.

Why does a C-Array have a wrong sizeof() value when it's passed to a function?

When you pass an array into a function in C, the array decays into a pointer to its first element. When you use sizeof on the parameter, you are taking the size of the pointer, not the array itself.

If you need the function to know the size of the array, you should pass it as a separate parameter:

void test(int arr[], size_t elems) {
/* ... */
}

int main(int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
/* ... */
test(point, sizeof(point)/sizeof(point[0]));
/* ... */
}

Also note that, for a similar reason (taking the sizeof a pointer), the sizeof(point)/sizeof(point[0]) trick doesn't work for a dynamically allocated array, only an array allocated on the stack.

Can the C++ Array class be passed as a parameter with variable size?

I am aware that a regular, built-in array can be passed in to a function with variable sizes.

No, it can't. It can only be passed in by-pointer or by-reference. In the case of by-pointer, all size information is lost. In the case of by-reference, the size has to be stated explicitly in the parameter itself as part of its type, thus you can't pass separate arrays of different sizes to the same function.

However, is there a good technique to be able to write a single function that takes an array class object reference, but the size can be variable?

Yes, use a template for the size, eg:

template<typename T, size_t N>
void doSomething(T (&arr)[N])
{
// use arr up to N elements as needed...
}
int arr1[5];
doSomething(arr1);

char arr2[10];
doSomething(arr2);

...

UPDATE: in the case of std::array, the template approach still works, eg:

template<typename T, size_t N>
void doSomething(std::array<T, N> &arr) {
// use arr up to N elements as needed...
}
std::array<int, 5> arr1;
doSomething(arr1);

std::array<char, 10> arr2;
doSomething(arr2);

...


Related Topics



Leave a reply



Submit