This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
How do I find the length of an array?
(30 answers)
Closed 8 years ago.
I am trying to write a short function which takes a pointer to an array and simply returns it's size. So far what I have is something like this:
int main (void) {
double MyArray[3] = {0, 1, 2};
int Temp = ArraySize(MyArray);
return 0;
}
int ArraySize(double * MyArray) {
return sizeof(MyArray) / sizeof(*MyArray);
}
But this doesnt seem to be working.
Any help appreciated,
Jack
That's impossible - the pointer simply points at the first element of the array. There's no way to extract the array size from that.
You could pass the array by reference, and infer the size as a template parameter:
template <typename T, size_t N>
size_t ArraySize(T (&)[N]) {return N;}
This will only work if you have access to the array itself (as you do in your example). If it's already decayed to a pointer, then the size information has been lost.
You cannot do what you want. MyArray in function ArraySize is a pointer to a double, not an array of doubles. You must explicitly pass the array length along with the base address of the array.
No it is not possible, you need to pass length in function with array. Like,
int ArraySize(double * MyArray, size_t length)
Related
This question already has answers here:
Finding length of array inside a function [duplicate]
(7 answers)
size of array passed to C++ function? [duplicate]
(7 answers)
Closed last year.
I am trying to pass an array through a function but when I try to get the length of the array it gives me the length of the pointer. Is there any way to convert the array pointer back into a regular array?
float arr[] = {10, 9, 8]
void func(float arr[])
{
// now I want to figure out the size of the array
int lenArr = sizeof(arr) / sizeof(arr[0]); // this will get the size of the pointer to the array and not the actual array's size
}
You can declare the parameter a reference to an array.
void func(float (&arr)[10])
{
// but you have to know the size of the array.
}
To get around having to know the size, you can template on size
template<int Size>
void func(float (&arr)[Size])
{
// Now the size of the array is in "Size"
// So you don't need to calcualte it.
}
I have read this answer
Adressing your question - pointer to array is usefull to pass an
entire array of compile-time known size and preserve information about
its size during argument passing.
But i don't really understand it. Aren't the size of arrays with a given size already known at compile-time? How do you get the size of the array if you have a pointer to it? Take this example:
void func(int (*array)[5])
{
}
// identical to
void func(int *array, int size)
{
}
You have to put 5 there, so what's the point of it? You still can't iterate over it unless you already know the size.
Aren't the size of arrays with a given size already known at compile-time?
Yes, they are.
How do you get the size of the array if you have a pointer to it?
You don't.
You have to put 5 there, so what's the point of it?
It prevents mistakes. You can only pass an array of the correct size to this function; the compiler will reject it if you try to pass a pointer, or wrongly sized array.
You still can't iterate over it unless you already know the size.
You can get the size from the array type:
size_t size = sizeof(*array) / sizeof(**array); // old school
size_t size = std::extent<decltype(*array)>::value; // C++11 or later
size_t size = std::size(*array); // the future, maybe
Or you could make the function a template, usable for any array size:
template <size_t N>
void func(int (&array)[N])
{
for (int i : array) // size is known
std::cout << i << '\n';
}
(I also changed the type to a reference rather than a pointer, to make the syntax clearer. It's possible that the answer you quote was for C, not for C++, in which case there are no references or templates.)
Adressing your question - pointer to array is useful to pass an
entire array of compile-time known size and preserve information
about its size during argument passing.
This is just true for char arrays as you don't need to pass size of array explicitly since its deduced by the null terminator.
When it comes to integer arrays (OR arrays where there is no terminator), I would say that they are not self-contained as passing pointer to array won't let that function to deduce the size of array. You have to pass size explicitly.
Mike Seymour's answer with the template example has made it click to me that you can use sizeof operator here.
void func(int (*array)[5])
{
std::size_t n = sizeof(*array) / sizeof(**array);
std::cout << n;
}
int main()
{
int array[5] = { 1, 2, 3, 4, 5 };
func(&array);
}
This approach works best in C, where you don't have templates.
if you have a pointer p point to the array
and you want to get the array size.
try size_t array_size = *(size_t*)p;
Dangerous. But it works.
This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 8 years ago.
I have the following function in C
int func(char* param1[], int param2[])
{
//Want to calculate size of param1 array
}
I tried
n = sizeof(param1)/sizeof(char*);
but this doesnt give me the correct answer.
Note that the function prototype
int func(char* param1[], int param2[]);
is equivalent to
int func(char **param1, int *param2);
This means the function parameters param1 and param2 are pointers, not arrays. Pointers and arrays are different types.
sizeof(param1) / sizeof(char*);
// equivalent to
sizeof(char **) / sizeof(char *) // always 1
The above expression always evaluates to 1 because size of all pointer types is the same (except for a function pointer on which sizeof operator may not be applied).
That's because you cannot pass an array to a function. What's actually gets passed is a pointer to the first element of the array. The pointer has no size information of the array passed to the function. Therefore, you must explicitly pass the array lengths to your function. It should have the prototype
int func(char *param1[], int param2[], int len_param1, int len_param2);
There are two ways of doing this:
Simplest and most obvious, pass the length in the function argument
Have a NULL at the end of the array (NULL-terminator):
char arr[] = { "what", "so", "ever", NULL }; Then loop:
int i;
for (i = 0; arr[i] != NULL; i++)
...
However, if you're passing an array like the example above to that function (a static one), just pass the length as an argument by using same logic...
func(arr, sizeof(arr) / sizeof(arr[0]);
C isn't smart enough to know the size of an array at runtime. It can only tell you the size of a data type, which is determined at compile-time.
The solution to this is to add a size parameter to the function, like this:
int func(char* param1[], int param2[], int n)
or to use a null-terminated array, so that you can use a loop to iterate through the array:
int func(char* param1[], int param2[]){
int size;
for(size = 0; param1[size] != NULL; size++);
...
The point is, an array in C is just a block of memory that you can happen to treat as a bunch of variables next to each other. There's no built-in way to figure out how many variables are in the block, since there's no built-in way to mark the beginning or end of the block.
char* param1[]
will make param a pointer of type char ** so the result of
n = sizeof(param1)/sizeof(char*);
is sizeof pointer by size of pointer i.e. 1. and its not size of array
This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
I need the use the length of a passed array 'X' in a function. The array is created in the main function. I print out the following from the main function:
std::cout << "\n" << sizeof(X);
which yields: 400
The array 'X' is then passed to a function where the length of X is needed. I print out the following from the function:
std::cout << "\n" << sizeof(X);
which yields: 8
I am expecting 400, as my array has 100 float elements. Why does sizeof() not return the same size as when it was called in the main function? (I assure you that there are actually 100 elements in array X because the rest of the program works.)
Thanks for any help!
When you pass a raw array (e.g. declared as int arr[100];) as a parameter to some other function, is it decayed into a pointer (whose size is often 8 on 64 bits processor).
So you declare your array
int arr[100];
then you declare your function
void f(int arr[]);
which is understood as
void (int *arr);
In C++11 you could use std::array so declare
std::array<int,100> arr;
and pass preferably a reference to it:
void f(std::array<int,100> &arr);
(you could pass it by value, but then all the 100 integers would be copied on function invocation).
BTW, consider also std::vector, and take many hours to read a good C++ programming book.
C arrays can be implicitly reduced to pointers and they will be. For sizeof to work correctly you would need to do the following:
template<size_t N>
void func(char (&arr)[N])
{
/* sizeof(arr) == N in this scope */
}
or you could use C++11 std::array.
In main the array size will be 4*100 = 400, but when you pass the address of array to another function it is now a pointer pointing to array, meaning the size of X is now size of pointer in called function.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculating size of an array
Sizeof an array in the C programming language?
Why does sizeof(arr)/(double)sizeof(arr[0]) work and sizeof(arr+0)/(double)sizeof(arr[0]) not work?
And why does sizeof(arr)/(double)sizeof(arr[0]) also not work when arr is passed to a function? Here is the full code example:
#include <iostream>
using namespace std;
int givesize(int arr[])
{
cout<<sizeof(arr)/(double)sizeof(arr[0])<<"\n";
}
int main()
{
int arr[] = {1,2,3,4,5};
cout<<sizeof(arr)/(double)sizeof(arr[0])<<"\n";
cout<<sizeof(arr+2)/(double)sizeof(arr[0])<<"\n";
givesize(arr);
return 0;
}
Output
5
1
1
This happens because arrays decay to pointers when they are passed to functions that take pointers as arguments.
Inside your main, the
int arr[] = {1,2,3,4,5};
declaration is equivalent to
int arr[5] = {1,2,3,4,5};
because the compiler has enough information to calculate the 5 from the aggregate initializer. In the function header, however, int arr[] does not mean the same thing: there is no context around it to tell the compiler that it's anything but a pointer to an integer.
int arr[] in a function argument list is the same as int* arr. Which means that in:
int givesize(int arr[])
{
cout<<sizeof(arr)/(double)sizeof(arr[0])<<"\n";
}
sizeof(arr)/(double)sizeof(arr[0]) is actually sizeof(int*) / (double)sizeof(int). As it outputs 1 that implies a 32-bit platform.
int arr[] as a local variable is not the same as int* arr, hence sizeof(arr)/(double)sizeof(arr[0]) is the same as sizeof(int[5]) / (double)sizeof(int) which evaluates to 5.
Next, sizeof(arr+2)/(double)sizeof(arr[0]) is again the same as sizeof(int*) / (double)sizeof(int), because the type of expression arr+2 is int*.
Inside main, arr has type "array of five ints", but arr+0 has type "pointer to int". When you add zero to arr, you are treating it like a pointer, and as soon as you use an array like a pointer, it gets converted to a pointer.
Why does sizeof(arr)/(double)sizeof(arr[0]) work
Because sizeof(arr) returns the size of the entire array in bytes (let's say 20 assuming int is 32 bits), and sizeof(arr[0]) returns the size of the first int (which is 4 bytes). This will give us 5.
And why does sizeof(arr)/(double)sizeof(arr[0]) also not work when arr is passed to a function?
Because arrays decay into pointers. This means they lose an important piece of information: their size. We cannot directly calculate the size of an array just by a pointer. How would the function even know it is an array to begin with?
C++? Use a template function:
template <typename T, int N>
int getsize(const T (&arr)[N])
{
return N;
}