0

I write a function in c++ that should count number of elements an array has. function receive array as its parameter. so I try the following method:

int countArray(int a[])
{
    int size = 0;
    while(a[size] != NULL)
    {
        size++;
    }
    cout<<"number of array elements are : "<<size<<endl;
}

this function work but not perfectly. when i pass an array to this function which has same number of elements as its size int one[3] = {1,2,3} or an unsized array it will return result with one more element. for example for the previous array one[3] it will display number of array elements are 4.
but in other situation it work fine. for example if I pass an array that has less element than its size int two[4] = {1,2,3} it will work.
I should use array in this example not vector or struct , so what should i do or what is the reason that function doesn't work with that kind of array as its parameters.

Ali Ansari
  • 152
  • 1
  • 1
  • 15
  • 3
    You cannot find that size. You need to pass it as an argument, use a template to pass the size or use a proper c++ container like `std::vector`. The idiomatic way of working on containers in modern c++ is to pass ranges (pairs of iterators). – François Andrieux Jul 11 '18 at 14:19
  • Arrays are bad. They don't know their size and like to shapeshift to pointers when used as function parameters. Throw them out the window. Use `std::vector` or `std::array` instead. – Ron Jul 11 '18 at 14:19
  • 3
    `a[size] != NULL` does **not** check whether there's an element in the array at that index – UnholySheep Jul 11 '18 at 14:20
  • as I mention i shouldn't use `vector` or `template`, so in this way there isn't any possible way? – Ali Ansari Jul 11 '18 at 14:21
  • 1
    Possible duplicate of [How to get size of dynamic array in C++](https://stackoverflow.com/questions/22008755/how-to-get-size-of-dynamic-array-in-c) – JLev Jul 11 '18 at 14:21
  • 1
    For sanity's sake replace `NULL` with `nullptr`. If it does not compile then your are not doing it correctly. – NathanOliver Jul 11 '18 at 14:22
  • I try to use `std::array` but it only work with fixed size array and in function parameter array should be unsize so it can accept array with different size. – Ali Ansari Jul 11 '18 at 14:22
  • 2
    @AliDK Then use `std::vector`. Variable length arrays are not allowed in portable C++ either. – Ron Jul 11 '18 at 14:23

3 Answers3

4

Once an array have decayed to a pointer (to its first element), there's no way of getting its size.

The loop you have can (and most likely will) go out of bounds and you will have undefined behavior.

There are three possible solutions:

  1. Use std::array instead

  2. Use std::vector instead

  3. Use array-size deduction with templates:

    template<size_t N>
    int countArray(int (&a)[N]) { ... }
    

Also note that C++ doesn't have the concept of "null" values. The symbolic constant NULL is for pointers only.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    as I mention I try `std::array` but it is for fixed size array and array parameter should be unsized. can I use `std::vector` as unsized array in function parameter? can you help with an example that how should I do this. – Ali Ansari Jul 11 '18 at 14:28
1

This function doesn't work when an array is used as a parameter, it decays into a pointer, and NULL is 0:

int a[5] = { 1,2,0,0,0 };
int countArray(int a[])
{
    int size = 0;
    while (a[size] != NULL)
    {
        size++;
    }
    cout << "number of array elements are : " << size << endl;
    return size;
}

The right answer is 5, but the output is 2.

You should change this function as follows:

int countArray(int a[], int size)
{
    cout << "number of array elements are : " << size << endl;
    return size;
}

And then you can call it like this:

int a[5] = { 1,2,0,0,0 };
countArray(a, 5);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Elvan
  • 11
  • 2
  • thank you for mentioning this point that I didn't realize before. i think I have to change the method i use because its not prefect. – Ali Ansari Jul 11 '18 at 15:04
0

I should use array in this example not vector or struct

From reading your comments and your inital post i just try to guess what data you are given and what you have to do. can it be that you are given an integer array with the following properties:

  1. at least one element
  2. the last element is guaranteed to be 0
  3. no other element except the last is 0

Then - and only then - the solution you tried would work. The example with int two[4] = {1,2,3} works because you create an array with 4 elements. but only initialize 3 with aggregate initialization. so the remaining (and so the last element) is set to 0.

The check for NULL with integers works the same as a check with 0.

phön
  • 1,215
  • 8
  • 20
  • it is not necessary that array should has at least one element, i suppose my function work if someone pass an empty array to it and it should return zero as its number of elements. and I got your point that why function work with larger array with less elements, because remaining elements are zero which is equal to null – Ali Ansari Jul 11 '18 at 15:01
  • the problem is: if the array is empty you are not allowed to access the first element. and thats what you do unconditionally in the while loop. and again: there is NO way you can "count" the array size, except you know which value the last element has (such as a delimiter) – phön Jul 11 '18 at 15:05