0

I have a snippet code in C programing language as shown below:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
    char *s="Abhas";
    printf(" s = %s \n", s);
    printf(" s + s[1] = %s \n", s+s[1]);
    printf(" s + s[1] - s[3]= %s \n", s+s[1]-s[3]);
    return 0;
}

and the output are: enter image description here

So, could you help me to clarify on how we get the second and the last output line. I am a new guy in C.

Limon Monte
  • 52,539
  • 45
  • 182
  • 213
NoName
  • 877
  • 12
  • 28
  • 1
    What result are _you_ expecting? – a3f Apr 08 '15 at 04:49
  • second last printf cause undefined behavior due to buffer overflow, get an idea from second part of [this answer](http://stackoverflow.com/a/15841740/1673391) – Grijesh Chauhan Apr 08 '15 at 04:50
  • Actually, I need an explaination for the question how the snippet code works, and why I get the output. – NoName Apr 08 '15 at 04:51
  • 1
    @GrijeshChauhan: I think so. s + s[1] = s + 'a' = s + 62 => error because the string has 5 characters only. – NoName Apr 08 '15 at 04:53
  • 1
    @PhucNguyen in `s + s[1]`, .. `s[1]` is `'b'` and its ascii value is 98 (assuming ascii implementation ) and `s + s[1]` == `s + 98` runtime error – Grijesh Chauhan Apr 08 '15 at 04:54

2 Answers2

4
printf(" s + s[1] = %s \n", s+s[1]);

is equivalent to:

printf(" s + s[1] = %s \n", s+'b');

which is equivalent to:

printf(" s + s[1] = %s \n", s+98);

That will access memory that it is not supposed to. The program exhibits undefined behavior.

The line:

printf(" s + s[1] - s[3]= %s \n", s+s[1]-s[3]);

is equivalent to:

printf(" s + s[1] - s[3]= %s \n", s+`b'-'a`);

which is equivalent to:

printf(" s + s[1] - s[3]= %s \n", s+1);

which is equivalent to:

printf(" s + s[1] - s[3]= %s \n", "bhas");

Hence the output.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Yeah, that's correct. I will accept your answer after 5 mins. Thanks – NoName Apr 08 '15 at 04:55
  • Look like it is the answer that I need. But I don't quite understand only more one thing. The compiler reads from top to bottom, from left right, but in s + s[1] - s[3], why s[1]-s[3] is calculated first? – NoName Apr 08 '15 at 07:01
  • @PhucNguyen, I showed the result of `s[1] - s[3]` just for illustration. The real operation will be `s + s[1]` first then the `- s[3]` on the result. – R Sahu Apr 08 '15 at 14:40
2

Think of memory laid out like this:

   | [0] | [1] | [2] | [3] | [4] | [5] | <- indexes
   +-----+-----+-----+-----+-----+-----+
s: |  A  |  b  |  h  |  a  |  s  | nul | <- characters
   |  65 |  98 | 104 |  97 | 115 |   0 | <- integral values (if ASCII)
   +-----+-----+-----+-----+-----+-----+

The following expression-address map shows what is happening:

s                                -> s       -> &(s[0])
s + s[1]                         -> s + 98  -> &(s[98])
s + s[1] - s[3]  -> s + 98 - 97  -> s + 1   -> &(s[1])

Of these, only the first and third are legal as they end up within the bounds of the string. The second is undefined.

The first gives you the address of the string itself, so you see Abhas.

The third gives you the address of the second character of the string, so you see bhas.

The second gives you something well outside the string and will therefore give you whatever it wants. In fact, as undefined behaviour, it can give you anything, nothing, crash, format your disks, laugh maniacally through your sound card, or even collapse to a naked singularity, taking a large chunk of our planet with it.


I should mention of course that, outside of educating you as to how pointers may work, that code should never be used or seen in the wild. It is a classic example of how not to code.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953