This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 8 years ago.
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;
}
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.
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.
Related
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
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
There is a further possibility that you could use, but calling it with too many different array sized might cause code bloat.
template<std::size_t N>
void binarySearch(int arr[N], int value)
And then use N instead of c.
This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 1 year ago.
So what's this line means? int n = sizeof(arr) / sizeof(arr[0])
Why are we dividing arr with arr[0] and whats the use of n here?
#include <iostream>
using namespace std;
int search(int arr[], int n, int x)
{
int i;
for (i = 0; i < n; i++)
if (arr[i] == x)
return i;
return -1;
}
// Driver code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int n = sizeof(arr) / sizeof(arr[0]);
// Function call
int result = search(arr, n, x);
(result == -1)
? cout << "Element is not present in array"
: cout << "Element is present at index " << result;
return 0;
}
From the C++ 14 Standard (5.3.3 Sizeof)
1 The sizeof operator yields the number of bytes in the object
representation of its operand...
If you have an array declared for example like this
int arr[] = { 2, 3, 4, 10, 40 };
then the expression
sizeof( arr )
yields the size of the memory occupied by the whole array.
The expression
sizeof(arr[0])
is the size of each element of the array because all elements of an array has the same size. As the type of array elements is int then you could write also
sizeof( int )
instead of
sizeof( arr[0] )
So the expression
sizeof( arr ) / sizeof( arr[0] )
yields the number of elements in the array.
Here is a demonstrative program.
#include <iostream>
int main()
{
int arr[] = { 2, 3, 4, 10, 40 };
size_t size_of_array = sizeof( arr );
std::cout << "The size of the memory occupied by the array is "
<< size_of_array << '\n';
size_t size_of_element = sizeof( arr[0] );
std::cout << "The size of the memory occupied by each element of the array is "
<< size_of_element << '\n';
std::cout << "The number of elements in the array is "
<< size_of_array / size_of_element << '\n';
return 0;
}
The program output is
The size of the memory occupied by the array is 20
The size of the memory occupied by each element of the array is 4
The number of elements in the array is 5
Pay attention to that the value of the expression has the type size_t instead of the type int.
If your compiler support C++ 17 then you can use standard function std::size declared in the header <iterator> instead of the expression sizeof( arr ) / sizeof( arr[0] ) like for example
#include <iterator>
//...
size_t n = std::size( arr );
As for the function search then it should be declared and defined like
size_t search( const int arr[], size_t n, int x )
{
size_t pos = 0;
while ( pos < n && arr[pos] != x ) ++pos;
return pos;
}
and in main you should write
size_t pos = search(arr, n, x);
( pos == n )
? cout << "Element is not present in array.\n"
: cout << "Element is present at index " << pos << '\n';
That line determines the size of the array. In C/C++ arrays (in contrast to Java) the size is not available. Since an array of n elements uses n times the size of a single element, you can calculate the number of elements like this.
This makes more sense when using templates where the actual size of an array element is unknown at compile time.
This question already has answers here:
Size of an array C++ [duplicate]
(7 answers)
Closed 2 years ago.
I am just starting to learn C++ and I was playing around with functions. I am trying to pass an integer array as a parameter, and have the function print every element of the array. My issue however is that I have an array initialized to a seize of 10, but when I pass it to the function it only reads it as a size of 2. Any help would be appreciated! You can find my program below.
#include <iostream>
#include <cmath>
using namespace std;
void Max(int Arr[])
{
for (int i=0; i<sizeof(Arr)/sizeof(Arr[0]); i++)
{
cout<< Arr[i]<<endl;
}
}
int main()
{
int Arr[]={1,2,3,4,5,6,7,8,9,10};
Max(Arr);
return 0;
}
Thank you all for the help in advance!
When an array is passed by value it is implicitly converted to pointer to its first element.
On the other hand a function parameter declared as having an array type is adjusted by the compiler to pointer to the array element type.
So for example these function declarations
void Max(int Arr[]);
void Max(int Arr[1])
void Max(int Arr[10])
void Max(int Arr[100]);
declare the same function and are adjusted by the compiler to the declaration
void Max( int *Arr );
As a result within the function the parameter Arr is a pointer and this expression
sizeof(Arr)/sizeof(Arr[0])
is equivalent to
sizeof( int * ) / sizeof( int )
that yields either 1 or 2 depending on the size of the type int *.
When you passing an array by value to a function you should also pass its size explicitly.
So the function could be defined like
void Max( const int Arr[], size_t n )
{
for ( size_t i = 0; i < n; i++ )
{
cout << Arr[i] << endl;
}
}
And the function can be called like
Max(Arr, sizeof( Arr ) / sizeof( *Arr ) );
Another approach is to declare the function parameter as having a referenced type. In this case it is better to use a template function that it could be called for an array at least of any size.
template <size_t N>
void Max( const int ( &Arr )[N] )
{
for ( size_t i = 0; i < N; i++ )
{
cout << Arr[i] << endl;
}
}
Or the function could be defined like
template <typename T, size_t N>
void Max( const T ( &Arr )[N] )
{
for ( size_t i = 0; i < N; i++ )
{
cout << Arr[i] << endl;
}
}
And the both functions can be called like
Max(Arr);
Pay attention to that you could use the standard class template std::array declared in the header <array>. For example
#include <iostream>
#include <array>
const size_t N = 10;
std::ostream & Max( const std::array<int, N> &a, std::ostream &os = std::cout )
{
for ( const auto &item : a )
{
os << item << ' ';
}
return os;
}
int main()
{
std::array<int, N> a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Max( a ) << '\n';
return 0;
}
The program output is
1 2 3 4 5 6 7 8 9 10
void Max(int Arr[]) is equal to void Max(int* Arr).
In function Max(int Arr[]):
sizeof(Arr)/sizeof(Arr[0]) = sizeof(int*)/sizeof(int)
On x64 it is equal 2, on x86 it is equal 1
correct your code:
---------------------------------
#include <iostream>
#include <cmath>
using namespace std;
void Max(int Arr[], int len)
{
for (int i=0; i<len; i++)
{
cout<< Arr[i]<<endl;
}
}
int main()
{
int Arr[]={1,2,3,4,5,6,7,8,9,10};
Max(Arr, sizeof(Arr)/sizeof(Arr[0]));
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Do the conditions of the for-loop always need constant?
How can I put sizeof function there to run an output showing all the elements of an array?
#include<iostream>
using namespace std;
void array_output(int a[])
{
for (int i = 0; i < (sizeof(a)) / (sizeof(a[0])); i++)
{
cout << a[i] << endl;
}
}
int main()
{
int a[] = { 22, 53, 13, 65, 80, 31, 46 };
array_output(a);
return 0;
}
i<(sizeof(a) output shows first 4 elements
i<(sizeof(a))/(sizeof(a[0])) output shows only the first element
instead of sizeof when 7 is directly used as a condition, it gives
the right output, showing all the elements.
†(This answer is for c++17 users...)
where no need of using sizeof operator at all.
Use instead std::size() function which will get you the size of the given container or array.
#include <iostream>
#include <iterator> // std::size
#include <cstddef> // std::size_t
int main()
{
int a[]{ 22,53,13,65,80,31,46 };
for (std::size_t i = 0; i < std::size(a); i++)
{
std::cout << a[i] << `\n`;
}
}
† Update
The OP has edited the question after posting this answer,
where the std::size can not be applied.
When the array a passed to void array_output(int a[]), it deduced to void array_output(int* a)
instead if of the its actual type int a[7].
i<(sizeof(a) output shows first 4 elements
Here, you are doing size of(int*) (pointer to int), depending up
on the architecture
it could be efferent. In your case it is 32 bit machine which is why you got sizeof(a) = 4.
i < sizeof(a)/ sizeof(a[0]) output shows only the first element
Dividing sizeof(a)(which is sizeof(int*) equal to 4 bytes in
your machine) by sizeof(a[0])(which is sizeof(int), also 4 bytes), is nothing but one and loops only once.
The #Timo's
answer, provide a templated function where size will be a non-type template parameter, which can be accessed directly, without going for sizeof.
How can I put sizeof in function and run an output showing all the
elements of an array?
This is possible only when passing the array a of actual type as it is.
For that, let the array to deduce to its int [7], by forwarding it perfectly.
#include<iostream>
template<typename Type>
void array_output(Type&& a) // deduced to `int a[7]`
{
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) { // or std::size(a)
std::cout << a[i] << '\n';
}
}
int main()
{
int a[] = { 22, 53, 13, 65, 80, 31, 46 };
array_output(a);
return 0;
}
If you use the actual array in the sizeof operator you will get the size of the array in bytes, meaning you can calculate the number of elements like you expected it using sizeof(array) / sizeof(array_type).
int x[] = {1, 1, 1, 1, 1, 1};
int sum = 0;
for (int i = 0; i < sizeof(x) / sizeof(int); i++)
sum += x[i];
// sum == 6
However if you pass the array as a function parameter you will encounter pointer decay. This means that the array size information is lost and you get the pointer size instead, which is the behavior that you described.
int sum(int arr[]) // arr decays to int*
{
int sum = 0;
for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
sum += arr[i];
return sum;
}
int main()
{
int x[] = {1, 1, 1, 1, 1, 1};
return sum(x); // will return 1 or 2, depending on architecture
}
You can still get the array size in the function if you use a template function for it.
#include <cstddef>
template <std::size_t N>
int sum(int (&arr)[N])
{
int sum = 0;
for (int i = 0; i < N; i++)
sum += arr[i];
return sum;
}
int main()
{
int x[] = {1, 1, 1, 1, 1, 1};
return sum(x); // will return 6
}
You can use vector for this.
vector<int> nums{1,2,3,4};
for(std::size_t i = 0; i < nums.size(); ++i)
cout<<nums[i]<<endl;
If you insist on using int a[], you should be aware of the size before traversing it.
By the way, on GCC
sizeof(nums) = sizeof(int) * total number of element
it's not the total number of element.
I trying to pass an array but don't understand why it gives me those errors. The code is also available in ideone.com
#include <iostream>
using namespace std;
class Max
{
int max = 0;
public:
int getMax(int array[], int size)
{
for(int num : array)
{
if(num > max)
max = num;
}
return max;
}
};
int main( )
{
Max m;
int arr[5] = { 5, 3, 2, 7, 6 };
cout << "Max number is: " << m.getMax(arr,5);
return 0;
}
The problem here as has been mentioned is that passing an array to a function it decays to a pointer. The fix that involves the least changes is to pass the array by reference like so:
template <int U>
int getMax(int (&array)[U])
this fix is probably not the most intuitive for a beginner though. The fix that requires a bit more changes and probably makes more sense to a beginner is to use std::vector or std::array:
int getMax(const std::vector<int> &array)
and in main:
std::vector<int> arr = { 5, 3, 2, 7, 6 };
cout << "Max number is: " << m.getMax(arr);
The cause is the for(:) can not get the size of "int array[]".
You have a size argument, but the begin() & end() can not use it. You must wrap the begin() and end() member functions or just simple it to
for(int i = 0; i< size; i++)
{
int num = array[i];
if(num > max)
max = num;
}
size argument needs type specified (proper type is size_t).
array in getMax function is a pointer (not an array). You can't use range-based for loop with it. You have to use regular for loop which will make use of size argument.