2

So i was playing with pointers to understand different use cases, I'm not so experienced at this and unable to wrap my head around some ideas. I'll mark the lines where i have a problem. Please help me understand pointers.

on line 6:

Why can't I refer a string as an array, since that's how it's stored in memory i think. How to access individual characters of a string?

on line 7-8:

why is there a difference of 8 bytes between &str and &str + 1 when int datatype takes 4-bytes

on line 9,10 and 12:

Why does using *str to refer to the string take int as input? and why does it cast a single byte char to int instead of casting 4 bytes?

char *str = "Ninechars";
printf("Start\n");
printf("%s\n", str);
printf("%p\n", str);    // address of first char of str
printf("%p\n", str+1);  // address of second char of str
// printf("%s\n", str[1]);  // [segfault] warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [TODO]
printf("%p\n", &str);   // address to head of the string? NO, address of the pointer var str
printf("%p\n", &str+1); // [TODO], difference of 8bytes b/w this and previous address value? [WHY]?
printf("%d\n", *str);   // what integer is this? -> whatever can be made from 'N'=78
printf("%d\n", *(str+1));   // 'i'=105, but why is it taking single byte ints [TODO]
printf("%ld\n", sizeof(1)); // 4 bytes, as expected
// printf("%s\n", *str);    // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO]
printf("End\n");
Output:
Start
Ninechars
0x40088f
0x400890
0x7fff95a594e8
0x7fff95a594f0
78
105
4
End

The full code file is here: http://ideone.com/ryag80

chrk
  • 4,037
  • 2
  • 39
  • 47
abhik
  • 60
  • 7
  • 1
    Line 6 expects a `const char*`, you're giving it a `char`. Likewise with line 12. – WhozCraig Nov 23 '14 at 07:03
  • When you give invalid arguments for conversion specifiers, it's undefined behavior. That's probably not what you wanted to hear, though. –  Nov 23 '14 at 07:04
  • [WhozCraig](http://stackoverflow.com/users/1322972/whozcraig) Thanks! that cleared up something, why does it revert to 'int' though? Is that the default mechanism? – abhik Nov 23 '14 at 07:14
  • You may find [this question](http://stackoverflow.com/questions/5045031/weird-result-when-use-d-specifier-to-print-a-unsigned-char-in-c) interesting. – WhozCraig Nov 23 '14 at 07:18
  • regarding this line: printf("%s\n", str[1]); %s is expecting the address of a char array, however you gave it the contents of a single char. suggest: printf("%s\n", &str[1]); which will print the 2 through last chars of the string – user3629249 Nov 23 '14 at 10:50
  • regarding this line: printf("%s\n", *str); %s is expecting the address of a null terminated char array, however you gave it the contents of the first char of the 'str' array. suggest: printf("%s\n", &str[0]); – user3629249 Nov 23 '14 at 10:51

1 Answers1

3

Let's examine it line by line:


char *str = "Ninechars";
printf("Start\n");
printf("%s\n", str);
printf("%p\n", str);    // address of first char of str
printf("%p\n", str+1);  // address of second char of str

The above addresses are part of the data segment of process' virtual memory.


printf("%s\n", str[1]);

Actually, str[1] == *(str + 1). What %s expects though is a char *, thus (str + 1) or &str[1].


printf("%p\n", &str);   
printf("%p\n", &str+1);

&str is the address of str, a pointer to char. It's on the stack.

The difference of 8 bytes means that, on your system, the size of a pointer to char is 8 bytes. Try printf("\nsizeof(char*) == %zd\n", sizeof(char*)) to verify it.


printf("%d\n", *str);

It's ASCII code for N.


printf("%d\n", *(str+1));

Indeed 'i' == 105 (ASCII code again), and you instructed printf() to print it as an int using %d.


printf("%ld\n", sizeof(1)); // 4 bytes, as expected
printf("%s\n", *str);    // [?]Wrong, [HOW][WHY], format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’[TODO]

Again, using %s, printf() expects a string (char * in C), but *str is actually a char (an 8-byte int).

chrk
  • 4,037
  • 2
  • 39
  • 47
  • [chrk](http://stackoverflow.com/users/2304215/chrk) Thanks a lot! just one more query, How do I know which addresses belong to stack and which ones belong to heap? – abhik Nov 23 '14 at 09:19
  • @abhik: Local variables are stored on the stack, `malloc`'d variables are stored on the heap. If you notice the values of the printed addresses you can verify that stack is in the beginning of process's virtual memory, while heap is in the end. I believe [this question](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap) is interesting and educational to learn more about stack and heap. – chrk Nov 23 '14 at 14:37