0

The sizeof() function in c++ is behaving very weird. I am unable to make any sense out of it. I was writing code to implement the binary search algorithm to find an element in an array. To have a lesser number of arguments in the function, I decided to get the length of the array using sizeof() function. Here is the code:

#include <bits/stdc++.h>

using namespace std;

int binarySearch(int arr[], int target) {
    int low = 0;
    int high = sizeof(arr) / sizeof(arr[0]) - 1;

    cout << "high is: " << high << endl;

    while (low <= high) {
        int mid = low + (high - low) / 2;

        if (arr[mid] == target) return mid;

        else if (arr[mid] > target) high = mid - 1;

        else low = mid + 1;
    }
    return -1;
}

int main() {
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    cout << binarySearch(array, 10) << endl;
    cout << "size of behaviour in main: " << sizeof(array);
    return 0;
}

The output is:

high is: 0
-1
size of behaviour in main: 40

On debugging, I realised that inside binarySearch function, the sizeof(arr) is giving me the size of int type i.e. 4. so sizeof(arr)/sizeof(arr[0])-1 = 4/4-1 = 0.

However, in int main, the sizeof(array) is giving me the size of int times length of the array i.e. 4*10 = 40.

What explains this change in behaviour of the sizeof() function with respect to its usage in int main and in function definition?

user9194161
  • 67
  • 1
  • 4
  • `int arr[]` is not an array in this context as you might think. Therefore `int high = sizeof(arr) / sizeof(arr[0]) - 1;` makes no sense. – Niclas Larsson May 12 '20 at 09:04
  • 1
    I am curious why you think something changed with c++11 – 463035818_is_not_an_ai May 12 '20 at 09:05
  • @NiclasLarsson I understand it now that arr is only a pointer, not an array. However, I still do not want to explicitly give int size in function argument. Is there any way around? – user9194161 May 12 '20 at 09:09
  • 2
    Take a look at `std::vector`. – Niclas Larsson May 12 '20 at 09:10
  • change the function to `template int binarySearch(int (&arr)[N], int target)`, then you have the size of the array as `N` in the function. The call site is the same. https://ideone.com/bt0Du1 – mch May 12 '20 at 09:11
  • [Why should I not #include ?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – Evg May 12 '20 at 09:13

2 Answers2

0

That doesn't work as you're getting the sizeof of a pointer. Refactoring the code to use a template is one solution:

#include <iostream>

using namespace std;

template<std::size_t N>
int binarySearch(int (&arr)[N], int target) {
    int low = 0;
    int high = sizeof(arr) / sizeof(arr[0]) - 1;

    cout << "high is: " << high << endl;

    while (low <= high) {
        int mid = low + (high - low) / 2;

        if (arr[mid] == target) return mid;

        else if (arr[mid] > target) high = mid - 1;

        else low = mid + 1;
    }
    return -1;
}

int main() {
    int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    cout << binarySearch(array, 10) << endl;
    cout << "size of behaviour in main: " << sizeof(array);
    return 0;
}

Using std::array is probably a better option. Both templates and std::array have sizes known at compile time. If you want a runtime approach, take a look at std::vector.

Niclas Larsson
  • 1,317
  • 8
  • 13
0

When u pass an array as an argument to a function.. it is passed as pointer ( int *arr).. thats why it is 4 ìn the binary search function.

suresh
  • 4,084
  • 10
  • 44
  • 59