Coffee Space 
Arrays are weird and sizeof() may not always work how
you expect. An array is not the same as a pointer and sometimes you will
come unstuck. There are several C-based solutions to this problem
depending on your specific needs, each with it’s role to play.
So we have some array, let’s say s - and we want to
determine the size in C. A pretty standard thing to do. So let’s do
it:
0001 int main(){
0002 char s[] = {"Hello World!"};
0003 printf("Size of 's' is %u\n", sizeof(s));
0004 }
This then outputs Size of 's' is 13, so all is good. But
we don’t plan to use it here, we plan to use it in some function, like
so:
0005 void test(char* s){
0006 printf("Size of 's' is %u\n", sizeof(s));
0007 }
0008
0009 int main(){
0010 char s[] = {"Hello World!"};
0011 test(s);
0012 }
The output is now Size of 's' is 8. Hang on a second!
What? sizeof() now fails to return the correct size because
I passed it to a function? That “8” seems familiar some how… It doesn’t
feel like a coincidence that it is the same size as a pointer…
This isn’t the first time I’ve run into this, my previous solution was to supply the length as an additional parameter, curl up into a ball and forget the problem exists. But not this time. This time I will grapple with the oddity (because I’m putting off doing more important work).
Okay, so apparently it is some kind of array pointer decay. I never formally got taught C or C++, so this was interesting to learn of indeed. I was under the impression that things wouldn’t do strange things in C, this is why I use it after all. But it turns out, this is not so much the case. Why do you do this to me?!
It turns out an array is a special thing, you can declare:
0013 char s[] = {"Hello World!"};
And this is a proper array. But if I pass this to a function normally (by pointer), information about size is lost.
It turns out there are several representations of the array:
char* a - By pointer.char a[] - By value.char (&a)[t]Without going into details that others
have, only functions that receive arrays by reference can use
sizeof() to determine array size.
So here we have a comparison of potential solutions (including the ones that don’t work):
0014 void test_ptr(char* a){
0015 printf("(ptr) Size of 'a' is %u\n", sizeof(a));
0016 }
0017
0018 void test_val(char a[]){
0019 printf("(val) Size of 'a' is %u\n", sizeof(a));
0020 }
0021
0022 struct Structure{
0023 char* a;
0024 unsigned int len;
0025 };
0026
0027 void test_str(struct Structure s){
0028 printf("(str) Size of 'a' is %u\n", s.len);
0029 }
0030
0031 void test_cnt(char* a){
0032 int len = 0;
0033 while(a[len++] != '\0');
0034 printf("(cnt) Size of 'a' is %u\n", len);
0035 }
0036
0037 void test_par(char* a, int len){
0038 printf("(par) Size of 'a' is %u\n", len);
0039 }
0040
0041 int main(){
0042 char s[] = {"Hello World!"};
0043 printf("Size of 's' is %u\n", sizeof(s));
0044 // by pointer
0045 test_ptr(s);
0046 // by value
0047 test_val(s);
0048 // structure method
0049 struct Structure z;
0050 z.a = s;
0051 z.len = sizeof(s);
0052 test_str(z);
0053 // count method
0054 test_cnt(s);
0055 // param method
0056 test_par(s, sizeof(s));
0057 }
This results in:
0058 Size of 's' is 13 0059 (ptr) Size of 'a' is 8 0060 (val) Size of 'a' is 8 0061 (str) Size of 'a' is 13 0062 (cnt) Size of 'a' is 13 0063 (par) Size of 'a' is 13
The counting method (test_cnt()) is really only
appropriate for simple array types that you know their terminating byte.
This is not reliable and is quite slow.
The structure method (test_str()) is fine enough, but it
could add complexity to your code, when all you really want is a simple
array. Inventing data types is all fine and dandy until your code grows
and is used by others.
The parameter method (test_par()) is probably ideal, as
long as the number of parameters you have is quite small. This is the
one I have been using for years as a workaround anyway.