1

I want to make a function in C++ that returns size of any array using pointers: *(&array + 1) - array. like this:

#include <iostream>
using namespace std;

void arrayLength(string array[]) {
    int arraySize = *(&array + 1) - array;
    
    cout << "Size of the array: " << arraySize << endl;
}

int main ()
{
    string myArray[] = {"a", "b", "c", "d"};
    arrayLength(myArray);
//  Output: It seems to return the size in bytes (different numbers like this: 381286345)

    return 0;
}

And this Code works:

#include <iostream>
using namespace std;

int main () {
    string array[] = {"a", "b", "c", "d"};
    cout << *(&array + 1) - array << endl;
    
    return 0;
}
Fady's Cube
  • 158
  • 1
  • 7
  • 2
    `&array + 1` is nonsense. What do you think `&array` in *every* context it is used in this code *does*. ? – WhozCraig Aug 15 '21 at 13:03
  • You cannot determine the size of a pointed to array from a pointer, so your function can never work – UnholySheep Aug 15 '21 at 13:04
  • 4
    https://stackoverflow.com/a/18078435/635608 – Mat Aug 15 '21 at 13:04
  • duplicate: [size of array passed to C++ function?](https://stackoverflow.com/q/3062005/995714), [When passing an array to a function in C++, why won't sizeof() work the same as in the main function?](https://stackoverflow.com/q/36525798/995714), [c++: array's size changed after passed to a function](https://stackoverflow.com/q/22187990/995714) – phuclv Aug 15 '21 at 13:10
  • In C++17 and later, use [`std::size()`](https://en.cppreference.com/w/cpp/iterator/size). – Ted Lyngmo Aug 15 '21 at 13:18

2 Answers2

2

Nice demonstration why are ordinary raw arrays dangerous.

The issue is with pointer arithmetic and +1. For T* ptr;, ptr+1 advanced the pointer by sizeof(T) bytes, or one T.

In main, &array is of type string(*)[4], so the pointer is incremented by sizeof(string)*4. This leads to the correct size.

On contrary, string array[] in arrayLength() has type string* even if you use []. The increment is only sizeof(string*) in bytes thus leading to incorrect size.

Just use std::array or std::vector with their size().

Quimby
  • 17,735
  • 4
  • 35
  • 55
1

I agree with the other answer that you should use std::array or std::vector if possible. If however, you are not allowed to use the STL or have other good reasons to use plain C arrays, then there is a possible template solution:

template<class T, size_t N>
size_t getArrayLength(T(&arr)[N])
{
    return N;
}

Just call this template with any array as parameter. Note that calling this with a pointer won't work, but at least you get a compiler error instead of weird runtime behaviour.

Brotcrunsher
  • 1,964
  • 10
  • 32