3

I am testing the sizeof operator. In two cases in my code, I get the size of the pointer (I think). In the other cases I get how many bytes the arrays occupy. How can I get the size of the array in bytes when I pass it to a function? Isn't the sizeof operator enough? Am I doing something wrong?

#include <stdio.h>

/*Testing the operator sizeof*/

void test (char arrayT[]);
void test2 (char *arrayU);

int main(int argc, char *argv[]){

    char array1[7];
    printf("array1 size is:%d\n", sizeof array1);
    /*array1 size is: 7*/

    char array2[] = { '1', '2', '3', '4', '5', '6', '7'};
    printf("array2 size is:%d\n", sizeof array2);
    /*array2 size is: 7*/

    char array3[] = "123456";
    printf("array3 size is:%d\n", sizeof array3);
    /*array3 size is: 7*/

    unsigned char array4[] = "123456";
    printf("array4 size is:%d\n", sizeof array4);
    /*array4 size is: 7*/

    char arrayX[] = "123456";
    test(arrayX);
    /*arrayT size is: 4*/

    char arrayY[] = "123456";
    test2(&arrayY[0]);
    /*arrayU size is: 4*/

    return 0;
}

void test (char arrayT[]){
    printf("arrayT size is:%d\n", sizeof arrayT);
}

void test2 (char *arrayU){
    printf("arrayU size is:%d\n", sizeof arrayU);
}
n233g16
  • 55
  • 1
  • 5
  • 3
    In `test2()`, there is simply no way of knowing the size of the array pointed to by `arrayU` unless you pass in another argument for the size (at least in the current state of the C++ standard). See [How to find the 'sizeof'(a pointer pointing to an array)?](https://stackoverflow.com/a/492410/865719) for more details. – maddouri Oct 19 '15 at 19:07
  • Possible duplicate of [c-sizeof-a-passed-array](http://stackoverflow.com/questions/5493281/c-sizeof-a-passed-array) – wrangler Oct 19 '15 at 19:12
  • @AlterMann That's not a good duplicate, OP obviously misses the fact (look at the example function signatures) that you actually **can't** pass an array and it will **always** decay as a pointer. –  Oct 19 '15 at 19:16
  • 3
    You cannot. You need to pass the size somehow, often as another formal parameter – Basile Starynkevitch Oct 19 '15 at 19:25
  • 1
    When you pass an array `a[]` as a parameter, it decays to a pointer `*a`, so the `sizeof a` returns nothing but the size of a pointer and `sizeof *a` returns nothing but the size of the storage for `1` of that `type`. – David C. Rankin Oct 19 '15 at 19:39
  • 1
    use correct format specifier %zu for printing value of sizeof otherwise you trigger undefined behaviour – Giorgi Moniava Oct 19 '15 at 19:46
  • Many comments/answers are saying `arrayT` "decays", however that is not right. It is *adjusted* to `char *arrayT`. Decay is something that happens to expressions. – M.M Oct 19 '15 at 20:12
  • While I do not doubt the accuracy of the technical distinction, there will be a whole lot more texts that need to be changed other than the comments above if *adjusted* should be used rather than *decay* to describe the process... – David C. Rankin Oct 19 '15 at 20:18
  • Good to see it's reopened and now *has* an answer getting to the key misunderstanding. –  Oct 19 '15 at 20:54
  • @M.M Agree "decay" is not the best verb here. The C spec uses "convert": "...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...". – chux - Reinstate Monica Oct 19 '15 at 21:25
  • well, "decay" is commonly used for this. Although "convert" is much more neutral, "decay" is not semantically wrong: it's somehow "reduced" in size (a pointer is typically smaller than the whole array) and information (you lose the knowledge about it's size). It may be "wrong" by the wording of the standard, but everyone still knows what's meant :) –  Oct 19 '15 at 21:37
  • @chux `arrayT` is not an expression that has type "array of type". I agree that "decay" is a suitable term for conversion of array expression to pointer, however that is a different situation from the type of a function parameter. See 6.7.6.3/7 for definition of "adjusted" – M.M Oct 19 '15 at 21:55
  • @M.M Agree that `arrayT` is not "array of type" and my [comment](http://stackoverflow.com/users/2410359/chux) applies to `main()`'s `array1[], ... arrayY[]` – chux - Reinstate Monica Oct 19 '15 at 22:02
  • I see.. my comment should be directed at @DavidC.Rankin . I'd be happy to see any text that describes adjustment (NOT array-to-pointer conversion) as "decay" changed to say "adjusted". Using the same word for two different things, especially when the second thing already has its own word, is confusing. – M.M Oct 19 '15 at 22:04
  • I don't mean to quibble, and we are likely talking about semantics, but are you saying the following answers are wrong? [**Array to pointer decay and passing multidimensional arrays to functions**](http://stackoverflow.com/questions/12674094/array-to-pointer-decay-and-passing-multidimensional-arrays-to-functions)?? – David C. Rankin Oct 19 '15 at 22:20

1 Answers1

7

When an array is passed to a function, what's actually happening is that a pointer to the first element in the array is being passed. Put another way, the array decays into a pointer to the first element.

In these two declarations:

void test (char arrayT[]);
void test2 (char *arrayU);

arrayT and arrayU are of exactly the same type due to this decay, and sizeof will return the same value for both, i.e. the size of a char *.

Contrast the above with this:

char array1[] = "a string";
char *array2;

Where array1 is actually an array of size 9, while array2 is a pointer whose size (on your system) is 4.

Because of this, there is no way to know the length of an array passed to a function. You need to pass in the size as a separate parameter:

void test (char arrayT[], size_t len);
dbush
  • 205,898
  • 23
  • 218
  • 273