Chris
Chris

Reputation: 163

Question about how Strings Change each other in C

This is a followup to a question I have asked before, but is different. This is more about technical how C works. So in the below code:

    char s[] = "#chromsize: chr1    249250621";
    char *p, *q, *chr;
    for (p = s + 11; isspace(*p) && *p != 0; ++p) {}
    assert(*p);
    printf("FLAG 1 (p): %s\n", p);
    for (q = p; *q != 0 && !isspace(*q); ++q) {}
    assert(*q);
    printf("FLAG 2 (p): %s\n", p);
    printf("FLAG 3 (q): %s\n", q);
    printf("FLAG 4 (q + 1): %s\n", q + 1);
    *q = 0;
    printf("FLAG 5 (q): %s\n", q);
    printf("FLAG 5.2 (p): %s\n", p);
    chr = p;
    p = q + 1;
    printf("FLAG 6 (q + 1): %s\n", q + 1);

And the output is

FLAG 1 (p): chr1    249250621
FLAG 2 (p): chr1    249250621
FLAG 3 (q):     249250621
FLAG 4 (q + 1): 249250621
FLAG 5 (q): 
FLAG 5.2 (p): chr1
FLAG 6 (q + 1): 249250621

So a few things confuse me. First, you'll notice that q+1 is the same before and after the line *q = 0 (FLAG 4 and FLAG 6). Why is this? It seems to change q (based on FLAG 3 vs FLAG 5), but still q+1 is the same.

Second, how does it work that after the line *q = 0, p goes from being equal to chr1 249250621 to just chr1 (FLAG 2, FLAG 5.2)?

Upvotes: 0

Views: 62

Answers (1)

hiddenAlpha
hiddenAlpha

Reputation: 400

Regarding Question 1:

In this situation we will have an array of chars somewhere in memory ("hello" in this example) and q knows at which address this array resides (eg 249250621 in your example)

This could look like:

q -----------.
             V
   +---+---+---+---+---+----+
   | h | e | l | l | o | \0 |
   +---+---+---+---+---+----+

So if we do a *q = 0 we will set the value where q is pointing to ('l' in my example) So after this action, we will have:

q ------------.
              V
   +---+---+----+---+---+----+
   | h | e | \0 | l | o | \0 |
   +---+---+----+---+---+----+
              ^
              ^-- We just wrote a null-byte here.

Now take a closer look: Only the value inside the array changed. q itself has not changed. It still points to the same memory location as it did before. (This is your 249250621)

For Question 2:

q and p are pointing to the same char array. So as we changed the memory, this will also be visible for p. Lets re-use the example from above and add p to the mix:

q ------------.
              |
p ---.        |
     |        |
     V        V
   +---+---+----+---+---+----+
   | h | e | \0 | l | o | \0 |
   +---+---+----+---+---+----+

As you see, if we print the "thing" which p points to, we will not see the whole string anymore because it is zero-terminated now in middle.

Upvotes: 2

Related Questions