This problem has been bugging me since forever. I have an array and in the scope of its declaration, I can use the sizeof operator to determine the number of elements in it but when I pass it to a function, it interprets as just a pointer to the beginning of the array and the sizeof operator just gives me the size of this pointer variable. Like in the following example,
#include<iostream>
int count(int a[]){
return (sizeof(a)/sizeof(int));
}
int main(){
int a[]={1,2,3,4,5};
std::cout << sizeof(a)/sizeof(int) << " " << count(a) << std::endl;
return 0;
}
The output of the code is 5 2. How so I pass an array to the function so that I could determine its size by the use of only the sizeof operator and won't have to pass on the extra size as a parameter to this function?
template<size_t N>
int count(int (&a)[N])
{
return N;
}
You cannot do that. There is no way of passing an array that will make it carry its size information with it. You have to do it yourself. You have to pass the count as an additional parameter.
Related
I am writing a simple function that returns the largest integer in an array. The problem I am having is finding the number of elements in the array.
Here is the function header:
int largest(int *list, int highest_index)
How can I get the number of integers in the array 'list'.
I have tried the following methods:
int i = sizeof list/sizeof(int); //returns incorrect value
int i = list.size(); // does not compile
Any help will be greatly appreciated!
C++ is based on C and inherits many features from it. In relation to this question, it inherits something called "array/pointer equivalence" which is a rule that allows an array to decay to a pointer, especially when being passed as a function argument. It doesn't mean that an array is a pointer, it just means that it can decay to one.
void func(int* ptr);
int array[5];
int* ptr = array; // valid, equivalent to 'ptr = &array[0]'
func(array); // equivalent to func(&array[0]);
This last part is the most relevant to your question. You are not passing the array, you are passing the address of the 0th element.
In order for your function to know how big the incoming array is, you will need to send that information as an argument.
static const size_t ArraySize = 5;
int array[ArraySize];
func(array, ArraySize);
Because the pointer contains no size information, you can't use sizeof.
void func(int* array) {
std::cout << sizeof(array) << "\n";
}
This will output the size of "int*" - which is 4 or 8 bytes depending on 32 vs 64 bits.
Instead you need to accept the size parameters
void func(int* array, size_t arraySize);
static const size_t ArraySize = 5;
int array[ArraySize];
func(array, ArraySize);
Even if you try to pass a fixed-sized array, it turns out this is syntactic sugar:
void func(int array[5]);
http://ideone.com/gaSl6J
Remember how I said that an array is NOT a pointer, just equivalent?
int array[5];
int* ptr = array;
std::cout << "array size " << sizeof(array) << std::endl;
std::cout << "ptr size " << sizeof(ptr) << str::endl;
array size will be 5 * sizeof(int) = 20
ptr size will be sizeof(int *) which will be either 4 or 8 bytes.
sizeof returns the size of the type being supplied, if you supply an object then it deduces the type and returns the size of that
If you want to know how many elements of an array are in the array, when you have the array and not a pointer, you can write
sizeof(array) / sizeof(array[0])
or
sizeof(array) / sizeof(*array)
There's no way to do that. This is one good reason (among many) to use vectors instead of arrays. But if you must use an array then you must pass the size of the array as a parameter to your function
int largest(int *list, int list_size, int highest_index)
Arrays in C++ are quite poor, the sooner you learn to use vectors the easier you will find things.
Pointers do not have information about the number of elements they refer to. If you are speaking about the first argument of the function call then if list is an array you can indeed use the syntax
sizeof( list ) / sizeof( int )
I would like to append that there are three approaches. The first one is to use arrays passed by reference. The second one is to use pointer to the first element and the number of elements. And the third one is to use two pointers - the start pointer and the last pointer as standard algorithms usually are defined. Character arrays have an additional possibility to process them.
The simple answer is you cannot. You need to store it in a variable. The great advantage with C++ is it has STL and you can use vector. size() method gives the size of the vector at that instant.
#include<iostream>
#include<vector>
using namespace std;
int main () {
vector<int> v;
for(int i = 0; i < 10; i++) {
v.push_back(i);
}
cout << v.size() << endl;
for(int i = 0; i < 10; i++) {
v.push_back(i);
}
cout << v.size() << endl;
return 0;
}
output:
10
20
Not tested. But, should work. ;)
You need to remember in a variable array size, there is no possibility to retrieve array size from pointer.
const int SIZE = 10;
int list[SIZE];
// or
int* list = new int[SIZE]; // do not forget to delete[]
My answer uses a char array instead of an integer array but I do hope it helps.
You can use a counter until you reach the end of the array. Char arrays always end with a '\0' and you can use that to check the end of the array is reached.
char array[] = "hello world";
char *arrPtr = array;
char endOfString = '\0';
int stringLength = 0;
while (arrPtr[stringLength] != endOfString) {
stringLength++;
}
stringLength++;
cout << stringLength << endl;
Now you have the length of the char array.
I tried the counting the number of integers in array using this method. Apparently, '\0' doesn't apply here obviously but the -1 index of the array is 0. So assuming that there is no 0, in the array that you are using. You can replace the '\0' with 0 in the code and change the code to use int pointers and arrays.
I am writing a simple function that returns the largest integer in an array. The problem I am having is finding the number of elements in the array.
Here is the function header:
int largest(int *list, int highest_index)
How can I get the number of integers in the array 'list'.
I have tried the following methods:
int i = sizeof list/sizeof(int); //returns incorrect value
int i = list.size(); // does not compile
Any help will be greatly appreciated!
C++ is based on C and inherits many features from it. In relation to this question, it inherits something called "array/pointer equivalence" which is a rule that allows an array to decay to a pointer, especially when being passed as a function argument. It doesn't mean that an array is a pointer, it just means that it can decay to one.
void func(int* ptr);
int array[5];
int* ptr = array; // valid, equivalent to 'ptr = &array[0]'
func(array); // equivalent to func(&array[0]);
This last part is the most relevant to your question. You are not passing the array, you are passing the address of the 0th element.
In order for your function to know how big the incoming array is, you will need to send that information as an argument.
static const size_t ArraySize = 5;
int array[ArraySize];
func(array, ArraySize);
Because the pointer contains no size information, you can't use sizeof.
void func(int* array) {
std::cout << sizeof(array) << "\n";
}
This will output the size of "int*" - which is 4 or 8 bytes depending on 32 vs 64 bits.
Instead you need to accept the size parameters
void func(int* array, size_t arraySize);
static const size_t ArraySize = 5;
int array[ArraySize];
func(array, ArraySize);
Even if you try to pass a fixed-sized array, it turns out this is syntactic sugar:
void func(int array[5]);
http://ideone.com/gaSl6J
Remember how I said that an array is NOT a pointer, just equivalent?
int array[5];
int* ptr = array;
std::cout << "array size " << sizeof(array) << std::endl;
std::cout << "ptr size " << sizeof(ptr) << str::endl;
array size will be 5 * sizeof(int) = 20
ptr size will be sizeof(int *) which will be either 4 or 8 bytes.
sizeof returns the size of the type being supplied, if you supply an object then it deduces the type and returns the size of that
If you want to know how many elements of an array are in the array, when you have the array and not a pointer, you can write
sizeof(array) / sizeof(array[0])
or
sizeof(array) / sizeof(*array)
There's no way to do that. This is one good reason (among many) to use vectors instead of arrays. But if you must use an array then you must pass the size of the array as a parameter to your function
int largest(int *list, int list_size, int highest_index)
Arrays in C++ are quite poor, the sooner you learn to use vectors the easier you will find things.
Pointers do not have information about the number of elements they refer to. If you are speaking about the first argument of the function call then if list is an array you can indeed use the syntax
sizeof( list ) / sizeof( int )
I would like to append that there are three approaches. The first one is to use arrays passed by reference. The second one is to use pointer to the first element and the number of elements. And the third one is to use two pointers - the start pointer and the last pointer as standard algorithms usually are defined. Character arrays have an additional possibility to process them.
The simple answer is you cannot. You need to store it in a variable. The great advantage with C++ is it has STL and you can use vector. size() method gives the size of the vector at that instant.
#include<iostream>
#include<vector>
using namespace std;
int main () {
vector<int> v;
for(int i = 0; i < 10; i++) {
v.push_back(i);
}
cout << v.size() << endl;
for(int i = 0; i < 10; i++) {
v.push_back(i);
}
cout << v.size() << endl;
return 0;
}
output:
10
20
Not tested. But, should work. ;)
You need to remember in a variable array size, there is no possibility to retrieve array size from pointer.
const int SIZE = 10;
int list[SIZE];
// or
int* list = new int[SIZE]; // do not forget to delete[]
My answer uses a char array instead of an integer array but I do hope it helps.
You can use a counter until you reach the end of the array. Char arrays always end with a '\0' and you can use that to check the end of the array is reached.
char array[] = "hello world";
char *arrPtr = array;
char endOfString = '\0';
int stringLength = 0;
while (arrPtr[stringLength] != endOfString) {
stringLength++;
}
stringLength++;
cout << stringLength << endl;
Now you have the length of the char array.
I tried the counting the number of integers in array using this method. Apparently, '\0' doesn't apply here obviously but the -1 index of the array is 0. So assuming that there is no 0, in the array that you are using. You can replace the '\0' with 0 in the code and change the code to use int pointers and arrays.
I'm trying to write a function that takes an array of any length as an argument and prints out each element in a new line, but since sizeof() returns its size in bytes, I tried dividing the size of the array by the size of a single element. When I tried running the programme passing an array with 9 elements, it only printed out the first two.
The function:
void PrintArray(int anArray[])
{
using namespace std;
int nElements = sizeof(anArray) / sizeof(anArray[0]);
for (int nIndex=0; nIndex < nElements; nIndex++)
cout << anArray[nIndex] << endl;
}
In order to find out what was wrong, I commented out the loop and added the statement
cout << sizeof(anArray) << " " << sizeof(anArray[0]) << endl;
and it printed out 8 4. How is it even possible for a 9 element array to be 8 bytes long? Does something happen to it when it's passed as an argument?
(Also, I have no clue how vectors work. I got started with C++ 3 days ago).
You can rely on sizeof to give you the size of an array, only within the scope of declaration.
For example:
void func()
{
int array[10];
int size = sizeof(array); // size = sizeof(int) * 10
// The size of 'int' depends on your compiler
}
void func(int array[10])
{
int size = sizeof(array); // size = sizeof(int*)
// The size of 'int*' is the same as the size of any other type of pointer
// It is typically 4 bytes on a 32-bit system and 8 bytes on a 64-bit system
}
In order to calculate the number of items in a given array (again, only in the scope of declaration), use:
int numOfItems = sizeof(array)/sizeof(*array);
In C and C++ arrays don't exist as function arguments, they are converted to pointers; doesn't matter how you declare it. Use std::vector instead.
The reason for the result you got is that you're obtaining sizeof() of a pointer, which will always return the native word size (4 for 32 bit machines, 8 for 64 bit) no matter what the pointed type.
anArray is a pointer, and pointers are 8 bytes on your system. int is 4 bytes on your system.
You have no way to determine the length of the array in this case; you'll need the caller (all the way up the line, if necessary) to pass it to you. Better yet -- use a C++ container (vector, etc.)
The only time sizeof() will work the way you expect is if the local definition of the variable indicates the array size.
When an array is passed by value as an argument of a function it is implicitly converted to a pointer to its furst element.
So these declarations are equivalent
void PrintArray( int anArray[] );
void PrintArray( int *anArray );
that is inside the body of the function parameter anArrayis a local variable with type int *. Pointers do not have information whether they point to a separate object or an object of some sequence.
Inside the function body operator
sizeof(anArray)
will return the size of an object of type int * that for your platform is equal to 8.
Usually such functions are declared as having two parameters: the pointer to the first element of the array and the size of the array
void PrintArray( const int anArray[], int n )
{
using namespace std;
for ( int i = 0; i < n; i++ )
cout << anArray[i] << endl;
}
It is better practice to use a vector in this situation unless there is some specific reason you need to use an array. For example, if you have a vector of integers, the following will work:
#include <iostream>
#include <vector>
using namespace std;
void PrintVector(vector<int>& aVector)
{
for (auto i : aVector)
cout << i << endl;
}
int main (int argc, char* argv[])
{
vector<int> v = {1, 37, 898, 463, 32, 2, 5};
PrintVector(v);
}
When executed, it will loop through all of the contents of the vector and print them.
I have a variable called names which is a two dimensional array.
I declared it like below so that there will be maximum of 5 names and each name will consist of 256 characters.
int main(){
char names[5][256];
strcpy(names[0],"John");
strcpy(names[1],"Matt");
printf("%d\n",sizeof(names)/256); //this prints out 5 which is correct
passit(names);
}
void passit(char names[][256]){
printf("%d\n",sizeof(names)/256); //this prints out 8 which seems to be a size of pointer
}
How should I change this so that in passit function, number of elements will be printed correctly?
Your code is C-style. If you're really writing C++ then I suggest using std::cout, std::vector and std::string:
void passit(std::vector<std::string> const& names) {
std::cout << names.size();
}
int main() {
std::vector<std::string> names(5);
names[0] = "John";
names[1] = "Matt";
std::cout << names.size();
passit(names);
}
Otherwise, you can perform an intermediate fix to your existing code.
As you've spotted, when you try to pass an array by value it actually decays to a pointer (char(*)[256] in this case) and you lose all information on the size of the first dimension.
Passing the array by reference avoids this, except that you now have to specify the full array type including all array dimensions; template argument deduction then makes this automatic:
template <size_t N>
void passit(char (&names)[N][256]) {
printf("%d\n", N);
}
If I write
int main()
{
int a[100] = {1,2,3,4,};
cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array,
//isn't it
return 0;
}
I get 400!
If I write
void func(int *a);
int main()
{
int a[100] = {1,2,3,4,};
func(a);
return 0;
}
void func(int *a)
{
cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array
}
Then I get 1!
So why function does not know the array size?
Arrays decay to pointers when passed to functions, so all you will get is the size of the pointer.
sizeof returns the size of the type. In the second example, func( int *a ), a is a pointer and sizeof will report it as such. Even if you did func( int a[100] ), a would be a pointer. If you want the size of the array in func, you must pass it as an extra argument.
This isn't working because sizeof is calculated at compile-time. The function has no information about the size of its parameter (it only knows that it points to a memory address).
Consider using an STL vector instead, or passing in array sizes as parameters to functions.
This was answered by Marcel Guzman in Calculating size of an array!
When passing your array as a parameter to a function taking a pointer, the array decays as a pointer.
void bar(int *a)
{
std::cout << sizeof(a) << std::endl; // outputs "4" (on a 32 bit compiler)
}
void foo()
{
int a[100] ;
std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
bar(a);
}
So perhaps the solution is to provide a correct function taking a reference to an array as a parameter :
template <size_t T_Size>
void bar(int (&a)[T_Size])
{
std::cout << T_Size << std::endl; // outputs "100" (on ALL compilers)
std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
}
void foo()
{
int a[100] ;
std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
bar(a);
}
Of course, the function must be templated.
No. You are wrong.
If I run your second part of code, it gives 1 on my computer. It's not 400.
#include <iostream>
void func(int *a);
using namespace std;
int main()
{
int a[100] = {1,2,3,4,};
func(a);
return 0;
}
void func(int *a)
{
cout<<sizeof(a)/sizeof(a[0])<<endl;
}
Produces
1
You get 400 the first time because you are passing only sizeof(a), not sizeof(a)/sizeof(a[0]), to cout. You need to wrap that calculation with parenthesis to get the correct value outputted, ie:
cout << (sizeof(a)/sizeof(a[0])) << endl;
For the second time, you should be getting 2, 4, or 8 (depending on architecture), definately not 400, since you are essentially outputting this:
cout << sizeof(int*) << endl;
Where the size of a generic pointer is always a fixed value.
A pointer is a pointer. That means, it simply points to memory, and that's all about it. Creating a pointer to an array (which usually means a pointer to the first element of the array, but not necessarily) is still only a pointer to some memory location. As a memory address is simply a memory address there is also no way for the pointer to know that the memory it is pointing to originally was an array, or how long that array was.
It's simply how pointers work. They point to memory, and that's all.
The function does not know the array size in your example because you took explicit steps to convert your array to pointer type, thus completely stripping the function parameter of its original array nature. Once again, you yourself took deliberate steps to make sure that the function does not know the size of the array. Under these circumstances, it is rather strange to see you ask the question about why the function doesn't know the array size.
If you what the function to receive its argument as an array, you have to pass it as an array, not as a mere pointer, and declare the corresponding function parameter accordingly. Arrays in C++ cannot be passed "by value", which means that you'll have to pass it "by reference", as one possibility
void func(int (&a)[100])
{
cout << sizeof a / sizeof a[0] << endl;
}