-1

When I am trying to pass an array and evaluate the size of that array using sizeof, it is giving wrong answer whereas it is producing correct result when done in main function:

 #include<stdio.h>
 #include<string.h>
 #include<stdlib.h>

 void fun(char c[])
 {
    printf("in fun, string = %s ,size of c = %d , sizeof c[0]= %d, strlen = %d\n",c,sizeof(c),sizeof(c[0]),strlen(c));
 }

 int main()
 {
     char c[]="(a(bc)d(e)f)";
     printf("in main, via sizeof -> %d, via strlen -> %d\n",sizeof(c)/sizeof(c[0]),strlen(c));
     fun(c);
     return 0;
 }

The output is:

in main, via sizeof -> 13, via strlen -> 12

in fun, string = (a(bc)d(e)f) ,size of c = 8 , sizeof c[0]= 1, strlen = 12

Compiler is :

gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)

infinite
  • 319
  • 1
  • 10
  • You cannot pass arrays in C, so it's passed as a `char*`, which is of size 8 on your platform. – zerkms Jul 10 '18 at 03:44

4 Answers4

2

As per C11 6.3.2.1 Lvalues, arrays, and function designators /3:

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue.

That means your array (of size 13) is decaying into a pointer (of size 8 since you appear to have 64-bit pointers) when passed to a function.

If you want to preserve the length, you'll have to do that yourself, such as with:

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>

 void fun(char *chPtr, size_t actualSz) {
    printf("in fun, str=%s, size=%zd, size[0]=%zd, strlen=%zd\n",
        chPtr, actualSz, sizeof(chPtr[0]), strlen(chPtr));
 }

 int main(void) {
     char chArr[]="(a(bc)d(e)f)";
     printf("in main, sizeof=%zd, strlen=%zd\n",
         sizeof(chArr)/sizeof(chArr[0]),
         strlen(chArr));
     fun(chArr, sizeof(chArr));
     return 0;
 }

You'll notice I've also changed the format specifiers to the correct size_t-based ones, and used a little more verbosity with respect to variable names.

This gives:

in main, sizeof=13, strlen=12
in fun, str=(a(bc)d(e)f), size=13, size[0]=1, strlen=12
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

c's size in a function is 8 because the array variable gets changed to a pointer for the function call.

Stephen Docy
  • 4,738
  • 7
  • 18
  • 31
1

When you compile your program, pay close attention to warnings. They are there for a reason.

warning: sizeof on array function parameter will return size of 'char *' instead of 'char []' [-Wsizeof-array-argument]

1

Other answers cite what the Standard says your code means. As a practical solution: you must pass the size of the array as another parameter, like memset() does (for example).

You could declare void fun( size_t n, char c[n] );. The c parameter is still converted to char*, sosizeof(c)will still give yousizeof(char*)instead ofn`, but at least that will tell the compiler what you meant and make it easier to catch out-of-bounds errors.

If the size is a constant known at compile time, you could declare it as

 #define CLEN 5

 void fun(char c[CLEN]);

Again, this still doesn't make sizeof do what you hoped, but it will enable many useful warnings about array-access bugs, so you should still do it.

Davislor
  • 14,674
  • 2
  • 34
  • 49