Search code examples
c++algorithmbinary-search

Trouble to find size of an Array & Output issue


I'm implementing Binary search. But I don't want to pass the size of an array as an argument in the binarySearch function. I'm trying to find array size in function. I use sizeof operator, but the output of the binary search is wrong. when I try to pass the size of array as an argument then the output is fine. My question is why & what is the problem for calculating array size in function? is it possible to calculate array size in function?

Here is my approach:

code

#include <bits/stdc++.h>
using namespace std;
void binarySearch(int arr[], int value)
{
   int c = sizeof(arr) / sizeof(arr[0]);
   
  //cout << c;
  int low = 0, high = c - 1, notFound = 1;

  while (low <= high)
  {
     int mid = (low + high) / 2;
     if (arr[mid] == value)
     {
        cout << "Found at index " << mid << endl;
        notFound = 0;
        break;
     }
     if (arr[mid] < value)
     {
        low = mid + 1;
     }
     else
     {
        high = mid - 1;
     }
   }

   if (notFound == 1)
   {
      cout << "Not Found" << endl;
   }
}
int main()
{
   int arr[] = {1, 2, 3, 4, 5, 6, 9, 56, 88};
   int x = 3;
   binarySearch(arr, x);
   //cout << p << endl;
}

output:

 tempCodeRunnerFile.cpp:5:22: warning: 'sizeof' on array function parameter 'arr' will return size of 'int*' [-Wsizeof-array-argument]
    int c = sizeof(arr) / sizeof(arr[0]);
                      ^
tempCodeRunnerFile.cpp:3:23: note: declared here
 void binarySearch(int arr[], int value)
                   ~~~~^~~~~
Not Found

My expected Output:

Found at index 2

Solution

  • My question is why & what is the problem for calculating array size in function

    The problem is that arr is a pointer to an element of the array. The size of the pointer has nothing to do with the size of the array, which is why your attempted sizeof(arr) cannot work.

    The warning message also explains this quite well.

    is it possible to calculate array size in function?

    Given only a pointer to an element, it is generally1 not possible to determine the size of the array. That is why you must pass the size as an argument.

    Another approach which I prefer is to encapsulate the pointer and the length in a class. There is a standard class template for this purpose: std::span.

    void binarySearch(std::span<int> arr, int value)
    {
       int c = arr.size();
       ...
    
    
    // call as in your example:
    int arr[] = {1, 2, 3, 4, 5, 6, 9, 56, 88};
    int x = 3;
    binarySearch(arr, x);
    

    1 There are techniques that allow this, but they have draw backs.

    One technique is to choose one element value as a "terminator" aka "sentinel" which signifies the end of the array. That way, you can do a linear search for the terminator to determine the length. This is commonly used in C with strings, where the null terminator character terminates the string. This technique isn't an option if you cannot dedicate any of the values as a terminator. The other obvious drawback is the linear complexity of the size calculation which is asymptotically more expensive than the binary search that you're implementing