0

Possible Duplicate:
Question about pointers and strings in C

#include<stdio.h>

int main()   
{    
char *str1="abcd";  
char str2[]="abcd";  
printf("%d %d %d\n",sizeof(str1),sizeof(str2),sizeof("abcd"));  
return 0;
}

Why does this code give same answers for sizeof(str2) and sizeof("abcd") even when str2 is ideally just like a pointer to a string , as is str1 ,so answer should be 4 4 5

Code on Ideone: http://ideone.com/za8aV

Answer: 4 5 5

Community
  • 1
  • 1
Dref D
  • 257
  • 2
  • 17
  • Sorry but that doesn't answer my question,why shouldn't str2 be same as str1 (in it's definition of being a pointer to a string) – Dref D Aug 29 '12 at 16:51
  • The first one is a pointer the second one is an array. A *pointer* and an *array*. They are two completely different things. That's why they "should not be the same". Why do you expect two completely different things to behave the same way? You know, it is very difficult to answer questions like this, when it is virtually impossible to even begin to understand why you find this behavior strange. You are basically asking "why cars are different from apples". How can one answer such a question? – AnT stands with Russia Aug 29 '12 at 16:57
  • hmm.. got it ,str2[] is equivalent to "abcd" in being an array of characters while str1 is a pointer , then can you please clear a doubt what exactly is str2[] , is it a pointer or a string? – Dref D Aug 29 '12 at 17:02
  • 1
    `str2` is an object of type `char [5]` (an array of 5 `char`s). In your example it happens to store string `"abcd"`. – AnT stands with Russia Aug 29 '12 at 17:05

2 Answers2

4

An array of characters is not a char pointer. Although arrays do decay to pointers when passed to functions, they are essentially different things (specifically, the compiler knows their exact length at compile time). The reason you see 5 for a four-character string is that string literals reserve one more char for the terminating zero. 4, on the other hand, is system-dependent: on systems with 32-bit pointers you will see 4, while on system with 64-bit pointers you will see 8

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • #include int main() { char *str1="abcd"; char str2[]="abcd"; printf("%c %c\n",*str1,*str2); printf("%d %d %d\n",sizeof(str1),sizeof(str2),sizeof("abcd"));\ return 0; } http://ideone.com/AZfCz I'm getting the same output, a,a for both *str1 and *str2 – Dref D Aug 29 '12 at 16:53
  • Added the bit about exact size known at compile time. It's important to explain the reasoning for the behavior, not just handwave and say "that's how it works." – Wug Aug 29 '12 at 16:54
  • @Wug Thanks, I was in the process of editing the answer adding more details - this is an important addition! – Sergey Kalinichenko Aug 29 '12 at 16:55
  • @dasblinkenlight could you please throw some more light on what you are trying to mean,according to my interpretation both str1 and str2 are pointers to a character string(array),and hence we should have an output as 4 4 5 – Dref D Aug 29 '12 at 16:57
  • @Dref D: Your interpretation is incorrect. `str1` is a pointer. `str2` is *not* a pointer. `str2` is an array. That's all there is to it. – AnT stands with Russia Aug 29 '12 at 16:59
  • @DrefD That is incorrect, `char str2[]` is not a pointer, it is an array with an implicitly defined size. It is the same as `char str2[5]` - the compiler lets you drop the `5`, because it can figure it out from the initializer, but that is the same thing. A declaration `char str2[]` becomes a pointer only when it is a declaration of a function parameter: `void foo(char str2[])`. – Sergey Kalinichenko Aug 29 '12 at 17:00
  • Thanks a lot for your time and help...I see I had mixed the two..thanks for clearing my doubt @dasblinkenlight – Dref D Aug 29 '12 at 17:07
1

Where did you get the idea that str2 is "ideally just like a pointer to a string"? It is not. str2 is an array. When operator sizeof is applied to an array, it returns the size of the array object in bytes.

String literal is also an array, so when sizeof is applied to a string literal, it returns the size of that array object in bytes. So, it is perfectly natural to expect sizeof("abcd") and sizeof(str2) to produce the same result. And they do.

P.S. %d is not an appropriate format specifier to print the result of sizeof. %d requires int argument, while sizeof produces a size_t value. Use %zu to print values of size_t type.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Use `std::ostream`, and don't worry about the actual types. – James Kanze Aug 29 '12 at 17:27
  • @James Kanze: It is actually an interesting question. Does `std::ostream` guarantee that it "knows" how to output values of `size_t` type? Of course, it has `<<` overloads for all built-in integral types, but `size_t` can be defined as a non-standard implementation-specific unsigned integral type. Granted, some suitable conversion will probably make it work in any case, but anyway... – AnT stands with Russia Aug 29 '12 at 17:36
  • I don't have access to the C standard here. The Posix standard requires that `size_t` not be larger than `long`; the page claims compatibility with the C standard here, but the way the requirement is worded makes me doubt; the language of the paragraph with this constraint is very unlike that of the C standard. For the rest: in practice, `size_t` will be one of the standard integral types, but it does look like there is an oversight on the part of the C++ standards committee: I would expect that `<<` be required for all extended integral types as well. – James Kanze Aug 29 '12 at 17:45