sizeof(char[]) lost if char[] passed into function?

I have some questions about the following code:

1. Why does sizeof(myCharray) go from 15 in main() to 4 in strInfo(). Is the only way to get correct size in strInfo by passing sizeof()=15 into strInfo as an extra parameter as in: strInfo(myCharray, sizeof(myCharray)) ?

2. Under what conditions will sizeof(...) return more than just the size of a type, as it does in main() when it returns 15?

3. shouldn't strlen(myCharray) take into account the fact that sizeof(myCharray)=15 and not search (for NULL) beyond end of array?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <string>
#include <iostream>

using namespace std;

void strInfo(const char myPtr[]) {
	//void strInfo(const char *myPtr) {
	printf("---strInfo------\n");
	printf("ptr(%p)\n", myPtr);
	printf("str(%s)\n", myPtr); 
	printf("strlen(%d)\n", strlen(myPtr)); 
	printf("sizeof(%d)\n", sizeof(myPtr));
}

int main()
{
	char myCharray[15];

	printf("sizeof myCharray(%d)\n", sizeof(myCharray));
	printf("strlen myCharray(%d)\n", strlen(myCharray));
	printf("str myCharray(%s)\n", myCharray);
	strInfo(myCharray);
	printf("\n\n");

	strcpy(myCharray, "test0001");
	printf("sizeof myCharray(%d)\n", sizeof(myCharray));
	printf("strlen myCharray(%d)\n", strlen(myCharray));
	printf("str myCharray(%s)\n", myCharray);
	strInfo(myCharray);
	printf("\n\n");

	return 0;
}


sizeof myCharray(15)
strlen myCharray(27)
str myCharray(╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╤ê6ÿ┤·¶)
---strInfo------
ptr(0014FA4C)
str(╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╤ê6ÿ┤·¶)
strlen(27)
sizeof(4)

sizeof myCharray(15)
strlen myCharray(8)
str myCharray(test0001)
---strInfo------
ptr(0014FA4C)
str(test0001)
strlen(8)
sizeof(4)

Press any key to continue . . .



1) Because void function(char foo[]) is the same as void function(char* foo). You're not passing an array, you're passing a pointer to the array. And if you do sizeof on a pointer, you get the size of a pointer (which is typically 4 on 32-bit systems) not the size of what it points to, since that is impossible to determine from the pointer alone.

2)

Under what conditions will sizeof(...) return more than just the size of a type


Never. The real question is "what is the type of myCharray". If you do sizeof() on an array name, you get the size of the full array. But note that while array names and pointers are syntactically similar, they are not the same, so sizeof() on a pointer is different.

3) No. Because you pass a pointer to strlen, it has no idea how large the buffer it points to is. There is no way to determine that from just the pointer, so all it does is keep searching until it finds the null terminator, which may beyond the end of the buffer if you fail to have your string properly null terminated.
Thanks Disch, I still need just a little clarification... in statement 1 you say char[] and char* are the same (as arguments to function(...)), but in statement 2 you say they are syntactically similar but not the same (as variable types declared in main())?

So if I understand you correctly, in main they are different, but once you pass them as arguments into a function they become the same. So there must be an implicit conversion from type: char[] to type: char* when a char[] is passed as argument into a function? So then the size of the char[] is lost, so there is information loss during the conversion from char[] to char*, is this correct?

The information loss is only during compile time. char *, char[], and char[k], when used as parameters, are always pointers. Pointers can point to arrays of any size, so the compiler has no idea what the size of the original array is.
On the other hand:
T array[constant];
array is an actual array, not a pointer, of size constant, and the compiler is aware of its size. A compiler could even be able to detect attempts to read or write past its limits.
Last edited on
I was a little unclear -- sorry about that.

- When declaring a function parameter, a name with brakets is a pointer.
- When declaring a variable, a name with brakets is an array.

1
2
3
4
5
6
void func(int someptr[])
{
  int somearray[5];
  // here, somearray is an array, because it was declared as a variable
  // but someptr is a pointer because it is a function parameter
}


So in main, 'myCharray' is an array, but when you pass it to strInfo you're really passing a pointer to it, and not the actual array itself.

So there must be an implicit conversion from type: char[] to type: char* when a char[] is passed as argument into a function?


This is correct. If you use an array name without its brakets, it can be (and usually is) implicitly cast to a pointer to the array. In fact I usually even have it in my head that "an array name without its brakets is a pointer". While this is applicable most of the time, it isn't really 100% true (this sizeof() situation is one of the very few times the differences are noticable).

So then the size of the char[] is lost, so there is information loss during the conversion from char[] to char*, is this correct?


Yes.

EDIT - blarg, helios is too quick.
Last edited on
Thanks helios and Disch for the very helpful explanations, I think I get it now.
Topic archived. No new replies allowed.