1

When I want to know the size of an array I do the following :

int array[30];
for(int i = 0; i < 30; i++) 
     array[i] = i+1; //Fill list
const int size = sizeof(array) / sizeof(array[0]);

But when I pass the array as argument in a function I will have a pointer in the function.

int size( int array[] )
{
    return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}

This obviously doesn't work. But how do I get the size of that array in a function without taking another parameter for the size?

8
  • 1
    @chris this is also tagged for c and c doesn't offer std::array :p Commented Oct 23, 2013 at 15:40
  • 1
    You can't using pure C. The int array[] in the method decays to a pointer - so there's no way to do it like that. Commented Oct 23, 2013 at 15:41
  • 2
    Using c-type arrays, you can't. You simply don't have the ability to know the length of an array after it's been passed, because 1) how easy it is to go beyond the bounds and 2) only the pointer to the first element is passed. The only exception is null-terminated strings. Commented Oct 23, 2013 at 15:41
  • 1
    @Davlog, Well, if it's tagged C++, I assume the OP uses C++. That's my rule, and if my C++ suggestions aren't appreciated, the tag should be removed. If they are, the C tag should be removed. Commented Oct 23, 2013 at 15:42
  • 6
    You do it differently in C and in C++. Pick your language. Commented Oct 23, 2013 at 15:43

5 Answers 5

5

how do I get the size of that array in a function without taking another parameter for the size?

You don't. The size of the array has to be somewhere visible to the compiler. Otherwise all you'll be able to pass is a pointer to the first element in the array.

However, you can use a template for the size, and make this a little more magical and seamless:

template <size_t N>  int size (const int (&ary)[N])
{
    assert (N == (sizeof(ary) / sizeof (ary[0])));
    return N;
}

And further templatizing the type of elements, so this works with arrays of anything:

template <typename T, size_t N>  int size (const T (&ary)[N])
{
    assert (N == (sizeof(ary) / sizeof (ary[0])));
    return N;
}
Sign up to request clarification or add additional context in comments.

Comments

2

This is the way to get the size of the array using function templates:

template <typename T, size_t N>
constexpr size_t size(const T (&)[N] ) // omit constexpr if no C++11 support
{
  return N
}

then

for(int i = 0; i < size(array); i++) { .... } 

but you could simplify things by using an std::array (or std::tr1::array or boost::array if you don't have C++11) and using it's size() method.

Comments

1

In C, arrays in function parameters behave very strangely. Frankly, I think the language was very badly designed here.

void foo(int data[10]) {
    int *p;
    int a[10];
}

sizeof(p) will probably be 4 (or maybe 8). And sizeof(a) will be 40 (or 80).

So what do you think sizeof(data) will be? If you guessed 40 (or 80), you're wrong. Instead, its size is the same as sizeof(p).

If a C compiler see a [ immediately after the name of a parameter, it removes it and replaces it with a pointer, and data[10] becomes *data. (This is different from the decaying behaviour we get with arrays elsewhere, when a parameter, arrays are dealt with more drastically).

In fact, the following will compile despite the different sized arrays:

int foo(int data[10]);
int main() {
    int hugearray[1000];
    foo(hugearray); // this compiles!
}

The C compiler doesn't respect, in any way, the size of array parameters. I believe that compilers should issue a warning on any array parameters, and encourage us to use the * directly. I might allow [], but certainly not [10] given that it's ignored by the compiler.

If you want your C compiler to respect the size of arrays, you should pass the address of the array.

int foo(int (*data)[10]);
int main() {
    int smallarray[10];
    foo(&smallarray); // OK
    int hugearray[1000];
    foo(&hugearray); // error, as desired
}

Returning to the original question, parameter arrays know nothing about their size.

Comments

0

Use Macro

int findSize(int array[])
{
//This will not return size off array,it will just get starting address array and no information about boundaries

    return sizeof(array) / sizeof(array[0]);

}
//But we can define a Macro for this

#define FIND_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))

int main()
{

    int SampleArray[30];

    printf("\nSize =%d ",sizeof(SampleArray) / sizeof(SampleArray[0]));
    printf("\nSize from Function =%d ",findSize(SampleArray));
    printf("\nSize from Macro =%d ",FIND_ARRAY_SIZE(SampleArray));
    printf("\n");

    return 0;

}

Comments

0

In C you can't find the size of array by passing array beginning address to function.

For example You have made function call

size(array); // You are calling function  by passing address of array beginning element 

int size( int array[] ) // this is same as int size(int *array)
{
    return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}  

Here sizeof(array) will give you the size of pointer. that is architecture dependent.

And if you pass character array instead of int array and that too if the character array was nulterminated then You can use strlen().This is the only way we can find the size of array.

strlen() counts till nul occurrence, You can use this trick However allocate memory for one more element to your array or declare your array with MAX_SIZE+1 .When ever if you store array elements of size n then store a known value inside array[n] and while finding size check against that value like strlen() Checks for Nul character.

2 Comments

You just repeat what OP said: "But when I pass the array as argument in a function I will have a pointer in the function. This obviously doesn't work."
@kotlomoy thanks for pointing this. added some more info in my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.