Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does anyone think there is something wrong in The C Programming Language 2E Page29?

Tags:

c

I am currently studying the well-known book for C - The C Programming Language, 2Ed. And when I trying the code in P.29, I think there is something wrong in the getline function:

int getline(char s[], int lim) {
    int c, i;

    for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; i++)
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        i++;
    }

    s[i] = '\0';
    return i;
}

What if when the for loop ended, i == lim-1 and c == '\n'? In this case, I think the array would be out of boundary, since s[lim] would be set to '\0'.

Does anyone think this is wrong? Thanks for your help.

like image 556
HackerYoung Avatar asked Jun 27 '13 02:06

HackerYoung


People also ask

Is the C programming language book still relevant?

It is still relevant and still very useful with regards to learning the language. Learning the language doesn't require you to implement new practices or styles that assist in code readability, etc.


2 Answers

The && operator has "early-out" semantics. This means that if i == lim-1, the rest of the condition is not executed - in particular, c = getchar() will not be called.

This means that in this case, c will have its value from the last iteration of the loop - and since the loop condition includes c != '\n', this value can't be '\n' (or the loop would have exited last time around).

This is true as long as lim is greater than 1, which must be a precondition of the function (because calling the function with lim less than or equal to 1 would cause the uninitialised value of c to be read).

like image 127
caf Avatar answered Oct 30 '22 21:10

caf


So, let's look at some cases:

If lim == 0:, then this will do undefined behavior. There's two places this will happen:

  • We will execute no iterations of the for loop, giving i == 0 and c == undefined.
  • We then access c at (c == '\n'). It has no defined value yet, so it's undefined behavior.
  • We then cause undefined behavior again by overflowing s with: s[i] = '\0';

What if lim == 1:

  • The for loop will not be run, because the condition is not met.
  • We will hit undefined behavior just like in lim == 0 because c has no value.
  • The last line will work fine.

What if lim == 2, and the input string is "ab":

  • The for loop will grab 'a', and place it into s.
  • The for loop will exit on the next iteration, with the value of c still being 'a'.
  • The if conditional fails.
  • The adding of the null character works fine.
  • So s == "a\0"

What if lim == 2 and the input string is "a\n" (Which is the case you're worried about):

  • The for loop will grab 'a', and place it into s.
  • The for loop will exit on the next iteration, with the value of c still being 'a'.
  • The if conditional fails.
  • The adding of the null character works fine.
  • So s == "a\0"
like image 22
Bill Lynch Avatar answered Oct 30 '22 19:10

Bill Lynch