2
char str[] = " http://www.ibegroup.com/";

char *p = str ;

void Foo ( char str[100]){

}

void *p = malloc( 100 );

What's the sizeof str,p,str,p in the above 4 case in turn?

I've tested it under my machine(which seems to be 64bit) with these results:

25 8 8 8

But don't understand the reason yet.

phihag
  • 278,196
  • 72
  • 453
  • 469
Je Rog
  • 5,675
  • 8
  • 39
  • 47

4 Answers4

4

sizeof(char[]) returns the number of bytes in the string, i.e. strlen()+1 for null-terminated C strings filling the entire array. Arrays don't decay to pointers in sizeof. str is an array, and the string has 25 characters plus a null byte, so sizeof(str) should be 26. Did you add a space to the value?

The size of a pointer is of course always determined just by the machine architecture, so both instances of p are 8 bytes on 64-bit architectures and 4 bytes on 32-bit architectures.

In function arguments, arrays do decay to pointers, so you're getting the same result that you get for a pointer. Therefore, the following definitions are equivalent:

void foo(char s[42]) {};
void foo(char s[100]) {};
void foo(char* s) {};
phihag
  • 278,196
  • 72
  • 453
  • 469
  • @phihag,what's the rationale for `In function arguments, arrays do decay to pointers`? – Je Rog Jun 25 '11 at 14:31
  • array(`char []`) and pointers(`char *`) are essentially the same thing,why treated differently? I'm expecting both are the same value... – Je Rog Jun 25 '11 at 14:33
  • @Je Rog arrays and pointers are **not** the same thing. Please follow the links to the C FAQ, the whole chapter discusses this in detail. In short, arrays become (or "decay" to) pointers in all contexts *except* `sizeof`, `&` and array initialization. – phihag Jun 25 '11 at 14:34
  • @Je Rog A `char*` and a `char[]` cannot ever have the same value, since they are of different types. They can, however, refer to the same position in memory. – phihag Jun 25 '11 at 14:38
  • `sizeof STRING_LITERAL` is not necessarily equal to `strlen(STRING_LITERAL) + 1`: imagine `#define STRING_LITERAL "foo\x00bar"` – pmg Jun 25 '11 at 14:38
  • @pmg Updated, this is indeed only true if the string is null-terminated and completely fills the array. – phihag Jun 25 '11 at 14:40
  • @phihag ,How would you declare a pointer to `&array` regarding this article? http://c-faq.com/aryptr/aryvsadr.html – Je Rog Jun 25 '11 at 14:45
  • @Je Rog A pointer to `&array` would be a `char** par[] = &&array;`, a pointer to `array` `char* par[] = &array;`. – phihag Jun 25 '11 at 14:54
  • @phihag ,I'm getting this error while doing `char *p3 [] = &str;`, `error: invalid initializer` – Je Rog Jun 25 '11 at 15:41
  • @Je Rog Sorry, my mistake. You need to put `*p3` in parentheses. The result is completely meaningless unless you're dealing with multi-dimensional arrays though. In detail: http://c-faq.com/aryptr/ptrtoarray.html – phihag Jun 25 '11 at 16:10
  • @Everyone: I'm a newbie but everyone is wrong about the string being 24 char plus 1 null. There are 25 real characters in that string -- count them. The length of a string does not include the null. Also, look at man strlen and see that it returns "the number of characters that precede the terminating NUL character." – grok12 Jun 25 '11 at 17:05
  • @grok12 That's what the third sentence in this answer says, isn't it? And the first sentence says `sizeof() == strlen()+1`. For example, for "ab", `sizeof() = 3 == strlen()+1 = 2 + 1`. – phihag Jun 25 '11 at 17:12
  • @phihag: Well, he's saying the answer should be 26 because of the null character. But the answer of 25 is correct since the null char doesn't count in the length. – grok12 Jun 25 '11 at 17:22
  • @grok12 `sizeof` does not care about the values of bytes in the `char[]`. Therefore, the `sizeof(" http://www.ibegroup.com/") == 26`, and `sizeof("ab") == 3`. The null character does not count for **`strlen`**, that's why `strlen("ab") == 2` and +1 is added to the result of `strlen` to get that of `sizeof` in my above comment and my answer. – phihag Jun 25 '11 at 17:32
  • @phihag: Well, now I'm really confused because I tried your "ab" example and it does return 3 just like you said. But there are 25 real characters in his string. I tried to run OP's code by my (OSX) compiler but it won't compile and complains about stray '\342' in program along with others. So I guess there are bad characters in the string which I copied and pasted. However I did carefully replace each char by typing over it but still got the same result. But I'm sure now that I am wrong and you are right about sizeof including the null. But I don't know what to make of the OP's string. – grok12 Jun 25 '11 at 17:56
  • @grok12 The OP string starts with a space, don't forget to count that. Also, it is rendered with smart quotes, probably an artifact of a translation through a WYSIWYG editor. – phihag Jun 25 '11 at 18:01
  • @phihag: I found my problem with his string. A missing ; (I did tell you I'm a newbie!). I ran it and the answer is 26. So I'll slink back into my cave and not come out for a while. – grok12 Jun 25 '11 at 18:03
1

The first is the sizeof of an built-in array, which is the amount of elements (24 + null on the end of the string).

The second is the sizeof of a pointer which is the native word size of your system, in your case 64 bit or 8 bytes.

The third is the sizeof of a pointer to the first element of an array which has the same size as any other pointer, the native word size of your system. Why a pointer to the first element of an array? Because size information of an array goes lost when passed to a function and it gets implicitly converted to a pointer to the first element instead.

The fourth is the sizeof of a pointer which has the same size as any other pointer.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • Pedantically speaking, not all pointers are necessarily the same size. – pmg Jun 25 '11 at 14:39
  • pmg: Dang, http://stackoverflow.com/questions/1241205/are-all-data-pointers-of-the-same-size-in-one-platform/1241314#1241314. Should I edit my answer or does this go out of the scope of the question? – orlp Jun 25 '11 at 14:57
  • I'd edit the answer (lol). Point is, there is wrong information in the answer. I'd sleep bad at night knowing I left (**confirmed**) [wrong information](http://xkcd.com/386/) hanging around. – pmg Jun 25 '11 at 15:01
  • A byte in C is not necessarily 8 bits. – paxdiablo Aug 03 '15 at 06:44
  • @paxdiablo I never claimed it is, generally. I only mentioned that it is for the asker's system. – orlp Aug 03 '15 at 07:09
  • Point taken. On re-reading, I may well have misunderstood. Cheers. – paxdiablo Aug 03 '15 at 10:29
0

str is an array of 8-bit characters, including null terminator.

p is a pointer, which is typically the size of the machine's native word size (32 bit or 64 bit).

The size taken up by a pointer stays constant, regardless of the size of the memory to which it points.

EDIT

In c++, arguments that are arrays are passed by reference (which internally is a pointer type), that's why the second instance of str has sizeof 8.

Tony the Pony
  • 40,327
  • 71
  • 187
  • 281
  • why the `sizeof` the 2nd `str` is not 100, like the 1st `str`? – Je Rog Jun 25 '11 at 14:27
  • @Je Rog: Because arrays get "promoted" to pointers when they appear as argument to a function. – DarkDust Jun 25 '11 at 14:29
  • @DarkDust: The promotion to pointer causes all info of the 100 to be lost so all sizeof can do is count out to the first null, right? – grok12 Jun 25 '11 at 19:46
-1

in the cases the size of

char str[] = “ http://www.ibegroup.com/”

is known to be 25 (24+1), because that much memory is actually allocated.

In the case of

void Foo ( char str[100]){

no memory is allocated

vsz
  • 4,811
  • 7
  • 41
  • 78