[comp.unix.wizards] Unix problem or C problem?

heilpern@ibd.BRL.MIL (Mark A. Heilpern ) (01/17/89)

	HELPHELPHELPHELPHELPHELPHELPHELPHELPHELPHELPHELP

	When running a program with the following code:

	while (fscanf(input,"%d",stars)!=EOF) {
		fprintf(stderr,"OK to this point.\n");
		fprintf(output,"%4d |",lines++);
		stars /= 50;
		for (count = 0; count <= stars; count++)
			fprintf(output,"*");
		fprintf(output,"\n");
	}

	I get the following error message, NOT put out from my program:

PROTECTION VIOLATION: name='plot', pid=15943, pc=a410cdc, ps=80000180
Illegal instruction

	Although this section of code indicates otherwise, I am using
	standard input and output. The "OK to this point" message does
	not appear when put in this position, however it does when placed
	one line above. (Still giving the error message :)

	The 'plot' program is not setu/gid, I've never seen a PROTECTION
	VIOLATION error like this before. Any insights would be greatly
	appreciated.

		Mark A. Heilpern, heilpern@brl.mil
-- 
 |\/|         |
 |  |   _     |<
/    \_(_(_)\_/ \______

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/18/89)

In article <245@ibd.BRL.MIL> heilpern@brl.arpa (Mark A. Heilpern (IBD) <heilpern>) writes:
>	while (fscanf(input,"%d",stars)!=EOF) {
>		fprintf(stderr,"OK to this point.\n");
>PROTECTION VIOLATION: name='plot', pid=15943, pc=a410cdc, ps=80000180
>	The "OK to this point" message does not appear when put
>	in this position, however it does when placed one line above.

Ahem.  Doesn't that TELL you something?  Like perhaps there is a
problem with the "while (fscanf(input,"%d",stars)!=EOF)"?  In
fact your problem is almost certainly that "stars" is not a pointer
to an integer as required by fscanf().  Perhaps you meant "&stars".

chris@mimsy.UUCP (Chris Torek) (01/18/89)

In article <245@ibd.BRL.MIL> heilpern@ibd.BRL.MIL (Mark A. Heilpern) writes:
>	while (fscanf(input,"%d",stars)!=EOF) {
>		fprintf(stderr,"OK to this point.\n");
>		fprintf(output,"%4d |",lines++);
>		stars /= 50;
>		for (count = 0; count <= stars; count++)
>			fprintf(output,"*");
>		fprintf(output,"\n");
>	}

Note especially the first complaint referring to fscanf.

% lint t.c
t.c:
t.c(6): warning: fscanf argument is type (int) rather than pointer (arg 3)
fprintf returns value which is always ignored
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

debra@alice.UUCP (Paul De Bra) (01/19/89)

In article <245@ibd.BRL.MIL> heilpern@brl.arpa (Mark A. Heilpern (IBD) <heilpern>) writes:
>...
>	while (fscanf(input,"%d",stars)!=EOF) {
>...
>		for (count = 0; count <= stars; count++)
>...
>	I get the following error message, NOT put out from my program:
>
>PROTECTION VIOLATION: name='plot', pid=15943, pc=a410cdc, ps=80000180
>Illegal instruction

From your piece of code it looks like "stars" is either an int,
in which the fscanf line should have &stars, or else it is a pointer to
an int, in which case the for-line should have *stars.

From the protection violation i deduce it is probably the first.
The error message seems strange though. I would expect a simple
Illegal instruction, core dumped or
Memory Fault, core dumped messge. You actually get a lot of info there.

Paul.
-- 
------------------------------------------------------
|debra@research.att.com   | uunet!research!debra     |
------------------------------------------------------

jeff@tekcsc.MKT.TEK.COM (Jeff Beadles) (01/19/89)

In article <245@ibd.BRL.MIL> heilpern@brl.arpa (Mark A. Heilpern (IBD) <heilpern>) writes:
$
$	HELPHELPHELPHELPHELPHELPHELPHELPHELPHELPHELPHELP
$
$	When running a program with the following code:
$
$	while (fscanf(input,"%d", & stars)!=EOF) {
    Shouldn't this be here -------^
$		fprintf(stderr,"OK to this point.\n");
$		fprintf(output,"%4d |",lines++);
$		stars /= 50;
$		for (count = 0; count <= stars; count++)
$			fprintf(output,"*");
$		fprintf(output,"\n");
$	}
$


Is it a case of the missing '&'?

		-Jeff Beadles
		 jeff@tekcsc.MKT.TEK.COM

andre@targon.UUCP (andre) (01/19/89)

In article <245@ibd.BRL.MIL> heilpern@brl.arpa (Mark A. Heilpern (IBD) <heilpern>) writes:
>	while (fscanf(input,"%d",stars)!=EOF) {
>		fprintf(stderr,"OK to this point.\n");

>PROTECTION VIOLATION: name='plot', pid=15943, pc=a410cdc, ps=80000180

I think this is a C problem namely yours. If you want scanf to fill
an integer for you, you must supply a pointer to that integer and
not the value of the integer so if you make your code to be:

	while (fscanf(input,"%d", &stars)!=EOF) {
		YOU FORGOT THIS _/^

the problem will go away.

	Hope this helps. Andre.

-- 
~----~ |m    AAA         DDDD  It's not the kill, but the thrill of the chase.
~|d1|~@--   AA AAvv   vvDD  DD        Segment registers are for worms.
~----~  &  AAAAAAAvv vvDD  DD
~~~~~~ -- AAA   AAAvvvDDDDDD        Andre van Dalen, uunet!mcvax!targon!andre

dg@lakart.UUCP (David Goodenough) (01/20/89)

From article <245@ibd.BRL.MIL>, by heilpern@ibd.BRL.MIL (Mark A. Heilpern ):
> 	When running a program with the following code:
> 
> 	while (fscanf(input,"%d",stars)!=EOF)
>	{
> 		fprintf(stderr,"OK to this point.\n");
> 		fprintf(output,"%4d |",lines++);
> 		stars /= 50;
> 		for (count = 0; count <= stars; count++)
> 			fprintf(output,"*");
> 		fprintf(output,"\n");
> 	}
> 
> 	I get the following error message, NOT put out from my program:

Try fscanf(input, "%d", &stars) 
			^
			^ TO ASSIGN INTO AN int, scanf() NEEDS THE ADDRESS

As an aside, I generally avoid testing scanf() values against EOF. scanf()
returns the number of successful assignments (1 in this case), so you may
be a lot safer saying:

	while (fscanf(input, "%d", &stars) == 1)
-- 
	dg@lakart.UUCP - David Goodenough		+---+
						IHS	| +-+-+
	....... !harvard!xait!lakart!dg			+-+-+ |
AKA:	dg%lakart.uucp@xait.xerox.com		  	  +---+

hudson@vsedev.VSE.COM (C Hudson Hendren III) (01/20/89)

In article <245@ibd.BRL.MIL> heilpern@brl.arpa (Mark A. Heilpern (IBD) <heilpern>) writes:
>
>	while (fscanf(input,"%d",stars)!=EOF) {
			         ^^^^^
You need to use an ampersand before the variable name so that fscanf has the
address of "stars".  The line should read:
	while (fscanf(input,"%d",&stars)!=EOF) {
>		fprintf(stderr,"OK to this point.\n");
>		fprintf(output,"%4d |",lines++);
>		stars /= 50;
>		for (count = 0; count <= stars; count++)
>			fprintf(output,"*");
>		fprintf(output,"\n");
>	}
>
>	I get the following error message, NOT put out from my program:
>
>PROTECTION VIOLATION: name='plot', pid=15943, pc=a410cdc, ps=80000180
>Illegal instruction
>
>	The 'plot' program is not setu/gid, I've never seen a PROTECTION
>	VIOLATION error like this before. Any insights would be greatly
>	appreciated.

It would appear that PROTECTION VIOLATION on you version of unix is what
most of us know to be a "segmentation violation".  This error occurs when
your program attempts to alter a memory location outside of it's allowed
area.

When you simply passed "stars" to fscanf() you were passing the actual value
of stars and not the address location of "stars".  The fscanf() function
expects an address.  If the value of "stars" happened to be zero, then
fscanf() would assume that you wanted the decimal number scanned in to be
stored at location zero.  This is either damaged another variable or it
clobbered an instruction (depending upon how your linker arranges the final
binary).  I guess that you clobbered an instruction since you got an illegal
instruction fault.
-- 
==> ..!uunet!vsedev!hudson  [hudson@vsedev.vse.com]  (C Hudson Hendren III) <==
==> These are my opinions and are not necessarily those of VSE Corporation. <==
==>	   MS-DOS was created to keep idiots away from UNIX computers	    <==

rbj@nav.icst.nbs.gov (Nilbert T Bignum) (02/14/89)

? As an aside, I generally avoid testing scanf() values against EOF. scanf()
? returns the number of successful assignments (1 in this case), so you may
? be a lot safer saying: ...

I agree. In fact, I would avoid testing the return value of scanf or
fscanf against *anything*. Don't use them at all. Use fgets followed
by sscanf. If you don't like the input on a particular line, it is
easier to throw it away by doing another fgets than by constructing
a scanf expression to read `any string terminated by newline but only
up to this many characters into that junk buffer over there'. On another
point, you may want to rescan the input somehow.

	Nilbert T Bignum <rbj@nav.icst.nbs.gov>
	NTSI: Never Twice the Same Institute

allbery@ncoast.ORG (Brandon S. Allbery) (02/20/89)

As quoted from <18366@adm.BRL.MIL> by rbj@nav.icst.nbs.gov (Nilbert T Bignum):
+---------------
| ? As an aside, I generally avoid testing scanf() values against EOF. scanf()
| ? returns the number of successful assignments (1 in this case), so you may
| ? be a lot safer saying: ...
| 
| I agree. In fact, I would avoid testing the return value of scanf or
| fscanf against *anything*. Don't use them at all. Use fgets followed
| by sscanf. If you don't like the input on a particular line, it is
| easier to throw it away by doing another fgets than by constructing
| a scanf expression to read `any string terminated by newline but only
| up to this many characters into that junk buffer over there'. On another
| point, you may want to rescan the input somehow.
+---------------

Using scanf() for interactive input has another wart:  if the (l)user
doesn't enter exactly the number of data items requested, s/he won't be
prompted properly for further input.  And it's (almost) impossible to catch
malformed data files in the non-interactive case.

++Brandon
-- 
Brandon S. Allbery, moderator of comp.sources.misc	     allbery@ncoast.org
uunet!hal.cwru.edu!ncoast!allbery		    ncoast!allbery@hal.cwru.edu
      Send comp.sources.misc submissions to comp-sources-misc@<backbone>
NCoast Public Access UN*X - (216) 781-6201, 300/1200/2400 baud, login: makeuser