5

I'm new to c programming. I want to create a function that takes an integer array as argument and returns length of the array. I know that the code below calculates the length correctly.

    int arr[] = {1, 2, 3, 4, 5};
    int length = sizeof(arr) / sizeof(arr[0]);

But if I create a function like below and pass the array as an argument, it doesn't work.

    int length_of(int* arr) {
        return sizeof(arr) / sizeof(arr[0]);
    }

My guess is that I'm not passing the array into the function correctly. What is the correct way of implementing this?

Atick Faisal
  • 1,086
  • 1
  • 6
  • 13

6 Answers6

4

Well, there's no way of getting this done from a function. Any array, passed to a function as argument will decay to a pointer type (to the first element). So, inside the called function, all you will get is a size of a pointer.

An indirect way of achieving this would be to have something called a sentinel value in the array, and from the called function, iterate over the array elements to find the sentinel value while incrementing a counter, and once found, take the length of that counter.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
3

Here's what the standard says (C99 6.3.2.1/3 - Other operands - Lvalues, arrays, and function designators):

Except when it is the operand of the sizeof 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.

This means that pretty much anytime the array name is used in an expression, it is automatically converted to a pointer to the 1st item in the array.

2

You are passing a pointer as the parameter into your function, so it is not possible to know the size of the array by just knowing the size of parameter you pass to the function.

The most standard way of calculating size of an array in C is the one you mentioned in your question:

int a[10];
size_t n = sizeof(a) / sizeof(a[0]);
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
Giriteja Bille
  • 168
  • 1
  • 13
2

As already answered, you cannot do this in a function. A common solution for that is to use a Macro. See e.g. Common array length macro for C?

yussuf
  • 635
  • 1
  • 4
  • 18
1

As other answers have pointed out, it is not possible to determine the size of an array inside of a function in the general case, i.e. without assumptions.

If this is really about returning the size of an array from a function at any cost, I chip in the general method of determining the length based on special knowledge/assumptions on the CONTENT of the array. This is how the strlen() function determines the length of NULLTERMINATED character sequences, which is the closest thing C has to string.
The special assumption on the content of the character sequence is that they only contain the terminating '\0' at the end. Many a StackOverflow question was asked because of the traps and vulnerabilities involved in that concept causing misunderstandings.

So, if you can for example assume that the array in question only contains non-negative integers (i.e. positive values and 0) and that the last valid value inside the array, at index (size-1), is negative, then you can determine the length of the array by search for that terminator, i.e. the first negative value you find at or behind the address from the pointer parameter.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • There is another answer here ( https://stackoverflow.com/a/65714715/7733418 ) with a more direct, but lets say also even more "ruthless" approach of returning the size of an array at any cost. I kind of admire that answer, but I miss the clear statement that they are really out on the "if you insist" angle, i.e. same approach as my answer. Otherwise I'd upvote there. ( @KrishnaAcharya ) – Yunnosch Jan 14 '21 at 07:51
  • I still stand with my duplicate proposal, assuming what OP is asking for is basically the same. But just in case I am wrong and the point of the question is really to find an original way of matching the seemingly impossible requirement, then this is a new contribution not covered by other answers yet. Edit: Just found the second paragraph of answer by @SouravGhosh , so I back down to "another explanation approach to a concept mentioned as a second thought in a different answer". Sorry was not reading carefully enough the first time through.... – Yunnosch Jan 14 '21 at 07:52
0

If your prime intention is to return the array size from the function then pass the size as the argument.

Because once the argument is passed to function it will be pointing to the first element

So the code goes like

#include <stdio.h>
int func_len(int number)
{
    return number;
}
int main()
{
    int arr[]={1,2,3,4,5};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("Length is %d\n",size);
    printf("Length is %d",func_len(size));
}

Output will be

Length is 5
Length is 5
krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
  • 4
    So the technical principle of this is "To return a value from a function calculate it outside beforehand and give it as a parameter.". Strictly speaking this answers the question, but it is unlikely the point of the question. Don't you agree? – Yunnosch Jan 14 '21 at 07:32
  • I think he wants to return length of array from a function in particular, So this is the only way he can do it – krishnaacharyaa Jan 14 '21 at 07:34
  • @Yunnosch better, the function is not at all needed, as the expected return value is already known. – Sourav Ghosh Jan 14 '21 at 08:06
  • 1
    @KrishnaAcharya it better be a sarcasm, as it's very poor programming practice, above anything else. – Sourav Ghosh Jan 14 '21 at 08:07
  • @SouravGhosh The function not being needed is my point here... The answer could be insightful if pointing this out and stressing the literal-mindedness. – Yunnosch Jan 14 '21 at 09:02
  • @Yunnosch I agree, that's why my comment to OP. – Sourav Ghosh Jan 14 '21 at 14:06
  • :-) A dangling carrot of two achievable upvotes..... Let's see. – Yunnosch Jan 14 '21 at 14:09