6

Trying to pass an int array of consecutive numbers starting with 1 but assuming the function receiving this array does not know it's length. When trying to calculate the length inside the function it just gives me 1 since it only finds the first element when calculating sizeof(arrayName).

#include <iostream>
using namespace std;

int Sum(int intArray[]) {
    int n = sizeof(intArray) / sizeof(*intArray);
    cout << "Array size in function: " << n << endl;
    return n * (n + 1) / 2;
}

int main() {
    int anArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int arraySum = Sum(anArray);

    cout << "Array size in main: " << sizeof(anArray) / sizeof(*anArray) << endl;
    cout << "Sum is: " << arraySum;
    int a;
    cin >> a;
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Instinct
  • 349
  • 1
  • 3
  • 10
  • 9
    Save yourself the pain, use a [`std::vector`](http://en.cppreference.com/w/cpp/container/vector), or [`std::array`](http://en.cppreference.com/w/cpp/container/array) – Borgleader Jan 29 '14 at 23:15

2 Answers2

16

Your function is taking a pointer to int. All size information is lost as you pass the array into the pointer. But you can use a function template to instantiate functions that match the right array size:

template <size_t N>
int Sum(const int (&intArray)[N])
{
  cout << "Array size in function: " << N << endl;
  return std::accumulate(std::begin(intArray), std::end(intArray), 0);
}

This Sum function will accept plain arrays or size known at compile time. However, it makes more sense to use std::array for these cases, or std::vector for cases when the size is chosen at runtime.

Note that the call to std::accumulate is just an example that solves the sum problem. It does not require knowledge of N, and could replace the function entirely. The size is taken care of by std::begin and std::end. You would need headers <numeric> and <iterator> for accumulate and begin/end respectively.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • +1, and imho, it makes more *"sense"* to use an iterator pair. Oh wait. thats `std::accumulate`. nm =P – WhozCraig Jan 29 '14 at 23:22
  • Thanks that does work well passing a consecutive array that starts with 1 then returning N * (N+1) / 2 but can't get it to compile using the accumulate return? Errors say those 3 aren't members of std – Instinct Jan 29 '14 at 23:33
  • @Instinct `#include ` and `#include ` – WhozCraig Jan 29 '14 at 23:36
  • hhmm with those includes it's still telling me accumulate/being/end aren't members of std o_O – Instinct Jan 29 '14 at 23:46
  • @Instinct [It works for me](http://ideone.com/aFNCMt). – juanchopanza Jan 29 '14 at 23:53
  • @Instinct I suspect you're not using a C++11 compliant toolchain. Writing your own within the belly of your `Sum` isn't difficult, and in fact can be tailored even to arbitrary types, so long as they support `operator +=` and trivial construction. [See it live](http://ideone.com/OuEugj). – WhozCraig Jan 30 '14 at 06:34
  • Are there any performance disadvantages using this template function to accept an array of any size, compared to simply also passing the size of the array to the function? This thread [link](https://stackoverflow.com/questions/60327543/is-it-bad-practice-to-template-array-sizes-when-calling-methods-that-take-in-arr) seems to go over some of it if I'm not wrong. – CreativiTimothy Jul 02 '23 at 18:38
2

In this function declaration

int Sum(int intArray[]);

array passed to it as an argument is implicitly converted to the pointer to the first element of the array. So this declaration is equivalent to

int Sum( int *intArray );

And the expression

int n = sizeof(intArray) / sizeof(*intArray );

is equivalent to

int n = sizeof( int * ) / sizeof( int );

if sizeof( int * ) is equal to sizeof( int ) then n will be equal to 1.

If you declare the parameter such a way as you did then you should also declare a second parameter that will accept the number of elements in the array. So I would rewrite the function the following way

int Sum( int intArray[], size_t n ) 
{
    int sum = 0;

    for ( size_t i = 0; i < n; i++ ) sum += intArray[i];

    return sum;
}

and in main I would call the function the following way

int arraySum = Sum( anArray, sizeof( anArray ) / sizeof( *anArray ) );

}

Also functions ususally are written to perform some general algorithms. It is a bad idea to write a function only for arrays that has sequantial values from 1 to some N.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335