2

I had a little issue: I can calculate the lenght of a vector but only if the vector is defined in the same function. When I try to pass the vector to another function it returns a wrong output and I don't understand why.

#include <stdio.h>

int len(int vec[]);

main()
{
    int a[6];

    printf("%d\n", sizeof(a)/sizeof(int));
    printf("%d\n", len(a));

    return 0;
}

len(int vec[])
{
    return sizeof(vec)/sizeof(int);
}    

the output is:

6
1

why the function len() doesn't work? It should return 6 instead of 1.

Shoe
  • 74,840
  • 36
  • 166
  • 272
JoulinRouge
  • 456
  • 4
  • 18
  • possible duplicate of [Sizeof an array in the C programming language?](http://stackoverflow.com/questions/1975128/sizeof-an-array-in-the-c-programming-language) – Lundin Feb 01 '13 at 12:16

3 Answers3

7

This is because arrays decay into pointers to their first elements when passed to a function.

There is no run-time storage of the length associated with the array, so this won't work. Basically for a function argument, a type such as int a[] is equivalent with int *a, i.e. it's just a pointer.

It's best to simply always pass a length when you need to pass arrays to functions, and you can never have a function like your len(). The exception is of course if you store the length yourself in the pointed-at data, like strings do with the terminator character.

As a stylistic point, this code in main():

printf("%d\n", sizeof(a)/sizeof(int));

is in my opinion better written as:

printf("%zu\n", sizeof a / sizeof *a);

With the following noteworthy changes:

  • The result of sizeof has type size_t, which is not an int. It's correctly printed by the format specifier %zu.
  • Note that sizeof is not a function, so the parenthesis are not needed in most cases.
  • Prefer to reference to variables, rather than repeating type names that may or may not be associated with the variables. sizeof *a means "the size of the value that a points at".
  • Also note that according to C's operator precedence rules, sizeof binds tighter than /, so the expression really means (sizeof a) / (sizeof *a), which is the desired result.
unwind
  • 391,730
  • 64
  • 469
  • 606
  • write a function that calculate a lenght passing it a lenght seems a bit useless :) but i understand. thanks a lot. – JoulinRouge Feb 01 '13 at 10:48
2

Your len function takes as an argument an array of unspecified size, in which case it is treated as just a pointer type (in your case, int pointer). On your particular platform, the size of the pointer is the same as the size of an int, so sizeof(vec)/sizeof(int) is 1.

If you specify explicitly the length of the array argument, then your size calculation will behave as expected -- but you the function will then only take array arguments of exactly that length.

See also: C++ arrays as function arguments

Community
  • 1
  • 1
sheu
  • 5,653
  • 17
  • 32
1

Because int len(int vec[]) is in reality a int len(int *vec). Inside of len the variable vec is seen as a pointer, thus sizeof vec returns the number of bytes needed for saving an address.

Note that sizeof is an operator, not a function. That means that the values retured by sizeof are calculated at compile-time.

Pablo
  • 13,271
  • 4
  • 39
  • 59