[comp.unix.programmer] Segmentation fault?

dave@cs.arizona.edu (Dave P. Schaumann) (02/25/91)

In article <38192@netnews.upenn.edu> widyono@eniac.seas.upenn.edu (Aasmodeus) writes:
>int getline(FILE *fp, char *line); /* decl. should it be line[]? */
>
>main(int argc, char *argv[])
>{
>  char line[BUFSIZ];		/* line of input */
>  while (getline(fp, line) > 0) {
>    printf("%s\n", *line);	
This is it ---------^ line is an array.  *line is the first character of that
array.  When printf sees "%s", it takes whatever the second parameter is, and
tries to indirect through it.  You can get the same effect by saying

  char c = 'x' ; *c = 'y' ;

A computer that has any kind of memory protection will almost certainly have
a segmentation fault at this point.

>  if (fgets(line, BUFSIZ, fp) == NULL)

Here is another, more subtle bug.  fgets will write up to BUFSIZ characters
(in this call) to line.  This is not including the final '\0' character.
The best thing to do is declare char line[BUFSIZ + 1], and all will be well.

-- 
Dave Schaumann      | Is this question undecidable?
dave@cs.arizona.edu |

dave@cs.arizona.edu (Dave P. Schaumann) (02/25/91)

Sorry if this appears twice.  The first time I tried to follow up, it appeared
that nothing actually got posted...

In article <38192@netnews.upenn.edu> widyono@eniac.seas.upenn.edu (Aasmodeus) writes:
>int getline(FILE *fp, char *line); /* decl. should it be line[]? */
>
>main(int argc, char *argv[])
>{
>  char line[BUFSIZ];		/* line of input */
>  while (getline(fp, line) > 0) {
>    printf("%s\n", *line);	
This is it ---------^ line is an array.  *line is the first character of that
array.  When printf sees "%s", it takes whatever the second parameter is, and
tries to indirect through it.  You can get the same effect by saying

  char c = 'x' ; *c = 'y' ;

A computer that has any kind of memory protection will almost certainly have
a segmentation fault at this point.

>  if (fgets(line, BUFSIZ, fp) == NULL)

Here is another, more subtle bug.  fgets will write up to BUFSIZ characters
(in this call) to line.  This is not including the final '\0' character.
The best thing to do is declare char line[BUFSIZ + 1], and all will be well.

-- 
Dave Schaumann      | Is this question undecidable?
dave@cs.arizona.edu |

dbc@cimage.com (David Caswell) (02/26/91)

In article <19099:Feb2505:49:2891@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
.> >  char line[BUFSIZ];		/* line of input */
.  [ ... ]
.> >  if (fgets(line, BUFSIZ, fp) == NULL)
.> Here is another, more subtle bug.  fgets will write up to BUFSIZ characters
.> (in this call) to line.  This is not including the final '\0' character.
.> The best thing to do is declare char line[BUFSIZ + 1], and all will be well.
.
.Uh, no. The fgets() interface was designed so that you could do things
.like fgets(line,sizeof(line),fp). Here it reads at most BUFSIZ - 1
.characters before the terminating null.

That is why it is so funny to see people do
while(fgets(str,1,fp)){
	...
}

for character-at-a-time input.

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (03/03/91)

As quoted from <944@caslon.cs.arizona.edu> by dave@cs.arizona.edu (Dave P. Schaumann):
+---------------
| >  if (fgets(line, BUFSIZ, fp) == NULL)
| 
| Here is another, more subtle bug.  fgets will write up to BUFSIZ characters
| (in this call) to line.  This is not including the final '\0' character.
| The best thing to do is declare char line[BUFSIZ + 1], and all will be well.
+---------------

fgets writes BUFSIZ-1 characters in all Unix and Unix-like systems I have
encountered, specifically to leave room for the trailing \0.  RTFM.

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY