Calculate size of array of character pointers [duplicate] - c++

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

Related

size of array being passed into function [duplicate]

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 5 years ago.
Complete example:
#include <stdio.h>
void test(int arr[]) {
int arrSize = (int)(sizeof(arr) / sizeof(arr[0]));
printf("%d\n", arrSize); // 2 (wrong?!)
}
int main (int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
int arrSize = (int)(sizeof(point) / sizeof(point[0]));
printf("%d\n", arrSize); // 3 (correct :-) )
test(point);
return 0;
}
Before passing it to a function, sizeof gives me the correct value. Doing the exact same thing on the exact same array in the function gives weird results. There's one element missing. Why?
When you pass an array into a function in C, the array decays into a pointer to its first element. When you use sizeof on the parameter, you are taking the size of the pointer, not the array itself.
If you need the function to know the size of the array, you should pass it as a separate parameter:
void test(int arr[], size_t elems) {
/* ... */
}
int main(int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
/* ... */
test(point, sizeof(point)/sizeof(point[0]));
/* ... */
}
Also note that, for a similar reason (taking the sizeof a pointer), the sizeof(point)/sizeof(point[0]) trick doesn't work for a dynamically allocated array, only an array allocated on the stack.
Because array is decayed to a pointer when passed as function argument, so sizeof gives you 4 and 8 for 32- and 64-bit platforms respectively.
Also, it's important to understand that sizeof is evaluated at compile time. Since that's the case, it doesn't make sense to expect different output in test() depending on what was passed in. The sizeof calculation was done when the function was compiled.
Because, when it's passed, only the pointer to array is actually being passed.
Your question is also answered at The C Programming FAQ. Question 6.21.
Because in C, C++, and Objective-C, functions cannot actually have array parameters. They only can have parameters that look like array parameters, but they aren't. In your example,
void test(int arr[])
the compiler sees "there is a parameter that looks like an array of int", and it replaces that parameter with a "pointer to int". So the function that you wrote is absolutely, one hundred percent, identical to
void test (int* arr)
Therefore, inside the function sizeof (arr) will give you the size of a "pointer to int".
Because sizeof() does NOT tell you the size of an array in C. It does something completely different.
sizeof C++ reference

Find the size of a c array in function [duplicate]

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)

Why do sizeof statsements produce different results? [duplicate]

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;
}

Size of operator return conflict

here is some code
class DengkleTryingToSleep{
public:
int minDucks(int ducks[]);
int temp(int ducks[]){
int size=sizeof(ducks);
cout<<"sizeof="<<size<<"\n";
}
};
int main (int argc, const char * argv[])
{
DengkleTryingToSleep dt;
int arr[]={9,3,6,4};
cout<<"sizeof "<<sizeof(arr);
cout<<"\nsizeof from function "<<dt.temp(arr);
return 0;
}
and output of this is
sizeof 16
sizeof from function sizeof=8
and i have no idea how this is working because it returns 16 (as expected when called inside main)
and returns 8 when called from the function
Because arrays decay to pointers when passed to a function. You're getting the size of a pointer in your temp function.
If you need to know the length of an array in a function ... you have to pass that in as well.
Actually this function:
int temp(int ducks[])
is exactly equivalent this function:
int temp(int *ducks)
There is NO DIFFERENCE at all. No difference. So no matter what you pass, whether an array or a pointer, it will become a pointer inside the function.
That means, when you write sizeof(ducks) in your function, it is exactly equivalent to sizeof(int*), which returns 8 on your machine (I guess, your machine has 64-bit OS where the size of pointer is 8 bytes).
If you want to pass an array, and don't it decay into pointer type, then do this:
template<size_t N>
int temp(int (&ducks)[N])
{
int size=sizeof(ducks);
cout<<"sizeof="<<size<<"\n";
}
Now it will print 16. Note that inside the function N represents the count of items in the array. So in your case, it would be 4, as there are 4 elements in the array. It means, if you need the length of the array, you don't need to calculate it as sizeof(bucks)/sizeof(int), as you already know the length of the array which is N.
Also note that there is a limitation in this approach: now you cannot pass dynamically allocated array:
int *a = new int[10];
dt.temp(a); //compilation error
//but you can pass any statically declared array
int b[100], c[200];
dt.temp(b); //ok - N becomes 100
dt.temp(c); //ok - N becomes 200
But in C++, you've a better option here: use std::vector<int>.
int temp(std::vector<int> & ducks)
{
std::cout << ducks.size() << std::endl;
}
//call it as
std::vector<int> v = {1,2,3,4,5,6}; //C++11 only, or else : use .push_back()
dt.temp(v);

Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]

This question already has answers here:
Why isn't the size of an array parameter the same as within main?
(13 answers)
Closed 5 years ago.
Complete example:
#include <stdio.h>
void test(int arr[]) {
int arrSize = (int)(sizeof(arr) / sizeof(arr[0]));
printf("%d\n", arrSize); // 2 (wrong?!)
}
int main (int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
int arrSize = (int)(sizeof(point) / sizeof(point[0]));
printf("%d\n", arrSize); // 3 (correct :-) )
test(point);
return 0;
}
Before passing it to a function, sizeof gives me the correct value. Doing the exact same thing on the exact same array in the function gives weird results. There's one element missing. Why?
When you pass an array into a function in C, the array decays into a pointer to its first element. When you use sizeof on the parameter, you are taking the size of the pointer, not the array itself.
If you need the function to know the size of the array, you should pass it as a separate parameter:
void test(int arr[], size_t elems) {
/* ... */
}
int main(int argc, const char * argv[]) {
int point[3] = {50, 30, 12};
/* ... */
test(point, sizeof(point)/sizeof(point[0]));
/* ... */
}
Also note that, for a similar reason (taking the sizeof a pointer), the sizeof(point)/sizeof(point[0]) trick doesn't work for a dynamically allocated array, only an array allocated on the stack.
Because array is decayed to a pointer when passed as function argument, so sizeof gives you 4 and 8 for 32- and 64-bit platforms respectively.
Also, it's important to understand that sizeof is evaluated at compile time. Since that's the case, it doesn't make sense to expect different output in test() depending on what was passed in. The sizeof calculation was done when the function was compiled.
Because, when it's passed, only the pointer to array is actually being passed.
Your question is also answered at The C Programming FAQ. Question 6.21.
Because in C, C++, and Objective-C, functions cannot actually have array parameters. They only can have parameters that look like array parameters, but they aren't. In your example,
void test(int arr[])
the compiler sees "there is a parameter that looks like an array of int", and it replaces that parameter with a "pointer to int". So the function that you wrote is absolutely, one hundred percent, identical to
void test (int* arr)
Therefore, inside the function sizeof (arr) will give you the size of a "pointer to int".
Because sizeof() does NOT tell you the size of an array in C. It does something completely different.
sizeof C++ reference