0

I have a quick question about the C sizeof() function. I'm passing an array into a function, and inside that function, I want to check the size of the array. However, regardless of the size of the input array, inside the function, it always seems to have a size of 4. For example:

void checkArraySize(char data[])
{
    int internalSize = sizeof(data); //internalSize is reported as 4
}

void main(void)
{
    char data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    int externalSize = sizeof(data); //externalSize is reported as 8

    checkArraySize(data);                                             
}

As the comments in the code state, before I call a function like checkArraySize(), I check the size of the array, and it shows 8. However, when I check the size of the array inside the function, it only reports as having 4 elements (it reports 4 elements regardless of the size of the input array).

More often than not, when I see issues like this, it's because there is a gap in my understanding of the topic. So, I'm sure I'm just missing something with how passing arrays works. If not, any ideas as to why this is happening?

Note: This is on a PIC32, so I'm using Microchip's MPLAB X IDE and XC32 compiler.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
detroitwilly
  • 811
  • 3
  • 16
  • 30
  • BTW: `sizeof` is not a function, but an operator. That's why you can use it on types (use parentheses) and expressions (no need for parentheses). The argument is not evaluated, unless it's a variably modified type, and thus the result is a compile-time constant expression. (If you hadn't said you are on an embedded system, I would have advised you that `main` always returns `int`. Things are more diverse in freestanding environments though.) – Deduplicator Nov 24 '14 at 00:52

3 Answers3

7
void checkArraySize(char data[])

will be translated to

void checkArraySize(char* data)

So, the code calculates the size of a pointer. 4 is the pointer size in your computer. In a 64-bit system, it will output 8.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Min Fu
  • 789
  • 1
  • 6
  • 16
4

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
kriyeta
  • 695
  • 4
  • 12
  • passed by reference? – tristan Nov 24 '14 at 01:44
  • @tristan passed by reference is here 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. I added example in answer. – kriyeta Nov 24 '14 at 03:59
  • C doesn't have 'reference'. it's array decaying to pointer i think. – tristan Feb 11 '15 at 03:42
1

Arrays are not copyable things in C and C++. Therefore inventors of thesele languages were forced to add somę non-intuitive automatic Type conversion from array to pointer onto their first element in order to offer programmer a way to pass array as argument to function.

Using sizeof operator (not a function) on such argument returns size of pointer Type rather than data size.

extra cents sizeof operator is expanded during compilation rather run time. From the other side passed Arrays to a function could have different sizes. So casting such Arrays to pointers has another one explanation: sizeof couldnt resolve size of different Arrays during compile time.

Anonymous
  • 2,122
  • 19
  • 26