Determining size of array returning strange values?

This is a discussion on Determining size of array returning strange values? within the C++ Programming forums, part of the General Programming Boards category; The following code returns 8 followed by 26, the second number obviously being correct and first being wrong despite having ...

1. Determining size of array returning strange values?

The following code returns 8 followed by 26, the second number obviously being correct and first being wrong despite having identical code. Any ideas what's wrong with my getarraysize function?

Code:
static char key[26] = {'r','t','c','t','b','f','n','l','a','f','s','t','t','t','s','e','a','n','i','m','(','m','o','c','i','r'};

int getarraysize(char *input) {

int output;
output = sizeof(input) / sizeof(input[0]);

return output;
}

int main(int argc, char *argv[]) {

cout << getarraysize(key) << "\n";
cout << (sizeof(key) / sizeof(key[0]));
return 0;
}

2. sizeof(input)
..here..only returns the size of the pointer, which is always same.

3. Nothing is wrong.
You just can't use sizeof() like that.

In order to count the elements of an array, the array has to be IN SCOPE.
Otherwise, all you have is a pointer, and sizeof tells you the size of the pointer.

4. I think that's because in the getarraysize function, sizeof(input) will give you the size of a pointer, which is 8, and sizeof(input[0]) is the size of a char, which is 1.

Originally Posted by edddo
The following code returns 8 followed by 26, the second number obviously being correct and first being wrong despite having identical code. Any ideas what's wrong with my getarraysize function?

Code:
static char key[26] = {'r','t','c','t','b','f','n','l','a','f','s','t','t','t','s','e','a','n','i','m','(','m','o','c','i','r'};

int getarraysize(char *input) {

int output;
output = sizeof(input) / sizeof(input[0]);

return output;
}

int main(int argc, char *argv[]) {

cout << getarraysize(key) << "\n";
cout << (sizeof(key) / sizeof(key[0]));
return 0;
}

5. OK thanks for that, so is there another way to find the size of an array passed as a function's argument?

6. No, unless you massage the data in some way (e.g., C-strings always ending in \0).

7. Actually, yes, there is. Let me show you an example in a minute or two.

EDIT:
Code:
#include <crtdefs.h>
#include <iostream>

template<typename T, size_t size>
size_t array_size(const T (&arr)[size])
{
return size;
}

int main()
{
int arr[20];
std::cout << array_size(arr);
}
You can also use std::array and std::vector which has a size() function.

8. Isn't this just 'managing the data in' like tabstop said? I am confident I am not as good of a programmer as you guys, but I'm pretty sure that C++ trickery wouldn't solve the OPs problem about the array not being in scope.

9. So long as you pass the full array type, such as replacing the T there with the actual type, no size information will be lost and you can always query the size.
If you pass the array to a function the usual way (T arr[n]), then the above method will not work.

10. Originally Posted by AndrewHunter
Isn't this just 'managing the data in' like tabstop said?
tabstop's phrase was actually "massage the data in some way". There is no need to tailor the data here, so no.

Originally Posted by AndrewHunter
I'm pretty sure that C++ trickery wouldn't solve the OPs problem about the array not being in scope.
The "trickery" is just a matter of avoiding the conversion to a pointer to the first element. If you pass a pointer to an array, then you need to know the array size, and the array is not converted to a pointer to its first element (unless you dereference the pointer and use the array in an applicable context within the function). From this you can write a function template to get the array size. It turns out that you can simplify by having the array passed by reference instead of passing a pointer to the array.

11. Hmm, I see. Thanks Elysia.

EDIT: Thank you as well Laser for your explanation.

12. Thanks I've integrated it into my program and it works but I'm having a little trouble understanding why it works. I don't know what the "T" is for. Also this usage of template is not what I'm used to, what's going on with that "size_t size" part?

You also mentioned replacing the "T" with the desired type (in my case "char") but when I try that I get a syntax error.

If you could explain a little bit that would really great

13. Originally Posted by edddo
Thanks I've integrated it into my program and it works but I'm having a little trouble understanding why it works. I don't know what the "T" is for.
It is as if you overloaded the function for each array type for which you provided an array as an argument to the function, e.g.,
Code:
size_t array_size(const int (&arr)[20])
{
return 20;
}
So you need the T because the element type is part of the array type.

Originally Posted by edddo
Also this usage of template is not what I'm used to, what's going on with that "size_t size" part?
It is just a template parameter.

14. Thanks very much.