Change of behavior when passing int array [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing an array as an argument in C++
Sizeof an array in the C programming language?
Can you please explain the output of the following code:
#include<iostream>
using namespace std;
void foo(int array[])
{
int size = sizeof(array) / sizeof(array[0]);
cout<<size<<endl;
}
int main()
{
int array[] = {1,2,3};
int size = sizeof(array) / sizeof(array[0]);
cout<<size<<endl;
foo(array);
return 0;
}
The corresponding output is:
3
2
Both the code inside foo() and inside main() looks similar to me so as to produce the same output, but it does not, can you please explain why?

void foo(int array[])
in C or C++ you cannot pass arrays by value, so the above declaration is interpretted as:
void foo(int * array)
Consider passing the array by reference:
template <size_t N>
void foo( int(&array)[N] )
{
cout << N << endl;
}

You are not passing the array into the function, you are passing the pointer to the array.
That means, in the function foo(), the result of sizeof(array) is the size of a pointer to an array of char, not the size of the array itself, so the function is effectively doing this:
cout << sizeof(int *) / sizeof(array[0]);
In this case size of int * is 8, size of int is 4, so you are getting an output of 2 from the function.

Related

Why does it say the length of the array is 1 in this function (C++)? [duplicate]

This question already has answers here:
getting size of array from pointer c++
(6 answers)
Closed 1 year ago.
So I'm trying to make a function that gets the length of an array by returning the sizeof the array and sizeof the integer type...
code:
#include <cstdio>
#include <iostream>
using namespace std;
int len(int *thing) {
return sizeof(thing) / sizeof(int);
}
int main() {
int fard[] = {100, 45, 1, 723, 500};
cout << len(fard);
}
... and when I run the code it just returns with 1
how do I fix this / what did I do wrong.
The function parameter has a pointer type
int len(int *thing) {
return sizeof(thing) / sizeof(int);
}
Even if you will rewrite the function like
int len(int thing[]) {
return sizeof(thing) / sizeof(int);
}
nevertheless the compiler will adjust the array type of the function parameter to the type pointer to the array element type as written in the first function declaration.
So within the function the expression sizeof(thing) yields the size of a pointer. If the size of a pointer is equal to the value of sizeof( int ) then the function returns 1.
You could write instead
template <size_t N>
size_t len(const int ( &thing )[N] ) {
return N;
}
and then
cout << len(fard);
to get the number of elements in the array fard.
Pay attention to that there is already standard C++ function std::size declared in the header <iterator> in C++ 17.
So you could write
#include <iterator>
//...
std::cout << std::size(fard);
Because sizeof(thing) / sizeof(int) is probably equivalent to 4 / 4 == 1.
Because thing is a pointer and pointers have a size of 4 bytes on 32-bit compilers.
Here:
len(fard)
when you pass fard to the function, it decays to a pointer. This means that it loses its size information. So inside the function len you are dividing a single pointer by sizeof(int).
Try this instead
#include <cstdio>
#include <iostream>
using namespace std;
template< std::size_t N >
int len(int (&thing)[N] ) {
return sizeof(thing) / sizeof(int);
}
int main() {
int fard[] = {100, 45, 1, 723, 500};
cout << len(fard);
}
Result:
Program stdout
5
Code: https://godbolt.org/z/qzdbqEYx1
By the way, on x86_64 your original code returns 2 = sizeof(64 bit pointer)/sizeof(32 bit int)

Sizeof in function [duplicate]

This question already has answers here:
determine size of array if passed to function
(10 answers)
size of array passed to C++ function? [duplicate]
(7 answers)
Closed 3 years ago.
How do I get the size of bits of an Array from a function
int NumberOfElements(int Array[]);
int main()
{
int Array[] = { 5,5,6,5,5 };
std::cout << NumberOfElements(Array);
}
int NumberOfElements(int Array[]) {
return sizeof(Array);
}
It's returning 4.
Result should be 20.
Arrays decay into pointers when passed as arguments to functions etc.
The size 4 means that the pointer has that size. It does not tell you anything about the number of elements in the actual array.
You may want to use a std::vector<int> instead where the size is part of its interface:
#include <vector>
int main()
{
std::vector<int> Array{ 5,5,6,5,5 };
std::cout << NumberOfElements(Array);
}
int NumberOfElements(const std::vector<int>& Array) {
return Array.size();
}

Passing an array of ints as an argument in C++? [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Passing Arrays to Function in C++
(5 answers)
What is array to pointer decay?
(11 answers)
Closed 9 years ago.
I made a function in C++ to find the length of an array. I find the sizeof the array passed in the argument and divide it by the sizeof the variable type. This should work but it always returns 1! Am I missing something obvious? Or does this have to do with pointers and memory? This is my code:
#include <iostream>
using namespace std;
int lengthOf(int arr[]);
int main() {
int x[] = {1,2,3,0,9,8};
int lenX = lengthOf(x);
cout << lenX;
return 0;
}
int lengthOf(int arr[]) {
int totalSize = sizeof arr;
cout << totalSize << endl;
int elementSize = sizeof(int);
return totalSize/elementSize;
}
Output (should be 6 instead of 1):
4
1
I am fairly new so excuse me if this is a bad question.
When passing an array as parameter, it always decays into a pointer. If you want to see the size of the array, you need to pass the array by reference, e.g.:
template <int Size>
int lengthOf(int (&array)[Size]) {
return Size;
}
You should use the pointer.
(sizeof(arr)/sizeof(*arr))
Even though int arr[] looks like you are passing an array, you are actually passing a pointer. int arr[] is equivalent to int* arr when used as a function parameter, this comes from C.
In C++, if you want to pass an array, the proper way is to do it by reference:
template <int N>
int lengthOf(int (&arr)[N]) {
int totalSize = sizeof arr;
cout << totalSize << endl;
int elementSize = sizeof(int);
return totalSize/elementSize;
}

C++ array size different result [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sizeof an array in the C programming language?
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
string a[] = {"some", "text"};
void test(string a[])
{
int size_of_a = sizeof(a) /sizeof(a[0]);
cout << size_of_a;
}
int _tmain(int argc, _TCHAR* argv[])
{
test(a); //gives 0
int size_of_a = sizeof(a) /sizeof(a[0]);
cout << size_of_a; //gives 2
return 0;
}
as u can see in the comment test(a) gives 0 instead of 2 as i would expect. Could someone explain why and how could i correct it? thanks
When you pass an array to a function, it decays to a pointer to the first element of the array and so within your test(string a[]) function
sizeof(a);
actually returns the size of a pointer and not the size of your array.
To prevent array decaing to pointer, you can pass reference to array to the function. But it causes types of array of function formal argument and actual argument must coincide (including their sizes). So you need to use template to make your function work with an array of any size:
template <int N>
void foo(const string (&a)[N])
{
int size_of_a = sizeof(a) /sizeof(a[0]);
cout << size_of_a;
}

Determining the quantity of elements in a C array

When print_array is called, the size of the int array[] parameter (count) isn't what was expected. It seems sizeof is not returning the size of the entire array which would be 5*sizeof(int) = 20.
namespace Util
{
void print_array(int array[])
{
size_t count = (sizeof array)/(sizeof array[0]);
cout << count;
// int count = sizeof(array)/sizeof(array[0]);
// for (int i = 0; i <= count; i++) cout << array[i];
}
}
int array_test[5]={2,1,5,4,3};
Util::print_array(array_test);
int array[] here becomes int* array, and sizeof(array) returns the same thing sizeof(int*). You need to pass an array by reference to avoid that.
template <size_t N>
void print_array(int (&array)[N]) {
std::cout << N;
}
int array[] = { 2, 1, 5, 4, 3 };
print_array(array);
Read this: it says the way to fix this, but for a quick description:
When a function has a specific-size array parameter, why is it replaced with a pointer?
Using sizeof(array) will work in the scope that the array is statically defined in. When you pass it into a function though the type gets converted into a pointer to the array element type. In your case, when you're in print_array it is an int*. So, your sizeof in in the function will be the size of a pointer on your system (likely 32 or 64 bits).
You can get around this with some fancy syntax like so (from the link above):
If you want that the array type is preserved, you should pass in a
reference to the array:
void foo ( int(&array)[5] );
but I'd say just pass the size in as well as another parameter, its more readable.
As this array is implemented as a thin overlay on pointers, the variable you have is just a pointer, so sizeof will return the size of your pointer.
The only way to know the length of an array is to place a terminating object, as the null character in C strings.
There is no other way to determine the size of an array if you only have a pointer to it.
Here's a trick: you can take a reference to an array of fixed size. You can use this to template-deduce the size.
#include <iostream>
char a [22];
char b [33];
void foo (char *, size_t size)
{
std :: cout << size << "\n";
}
template <size_t N>
void foo (char (&x) [N])
{
foo (x, N);
}
int main () {
foo (a);
foo (b);
}
This prints 22\n33\n
void print_array( int array[] ) is synonymous with void print_array( int *array ). No size information is passed when the function call is made, so sizeof doesn't work here.
For an algorithm like this, I like to use iterators, then you can do what you want... e.g.
template <typename Iterator>
void print(Interator begin, Iterator end)
{
std::cout << "size: " << std::distance(begin, end) << std::endl;
std::copy(begin, end, std::ostream_iterator<std::iterator_traits<Iterator>::value_type>(std::cout, ", "));
}
to call
print(a, a + 5); // can calculate end using the sizeof() stuff...
just an addition to all the answers already posted:
if you want to use an array which is more comfortable (like an ArrayList in java for instance) then just use the stl-vector container which is also able to return its size
All the following declarations are exactly same:
void print_array(int array[]);
void print_array(int array[10]);
void print_array(int array[200]);
void print_array(int array[1000]);
void print_array(int *array);
That means, sizeof(array) would return the value of sizeof(int*), in all above cases, even in those where you use integers (they're ignored by the compiler, in fact).
However, all the following are different from each other, and co-exist in a program, at the same time:
void print_array(int (&array)[10]);
void print_array(int (&array)[200]);
void print_array(int (&array)[1000]);
int a[10], b[200], c[1000], d[999];
print_array(a); //ok - calls the first function
print_array(b); //ok - calls the second function
print_array(c); //ok - calls the third function
print_array(d); //error - no function accepts int array of size 999