home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: sparky!uunet!charon.amdahl.com!pacbell.com!ames!haven.umd.edu!darwin.sura.net!wupost!gumby!yale!yale.edu!ira.uka.de!math.fu-berlin.de!unidui!rrz.uni-koeln.de!Germany.EU.net!mcsun!sunic!ugle.unit.no!alf.uib.no!krill!yngvar
- From: yngvar@imr.no (Yngvar Foelling)
- Subject: Re: largest structure size on pc (in c)
- Message-ID: <1992Nov13.165506.27585@alf.uib.no>
- Sender: yngvar@krill (Yngvar Foelling)
- Organization: Institute of Marine Research, Bergen, Norway.
- References: <92314.235722U17868@uicvm.uic.edu>
- Date: Fri, 13 Nov 92 16:55:06 GMT
- Lines: 117
-
- In article <92314.235722U17868@uicvm.uic.edu>, <U17868@uicvm.uic.edu> writes:
- |> my program is listed below. it is very short. All I am trying to do is to
- |> read from a file. But, I think the problem is that the structure size is too bi
- |> g. It compiles successfully.I am using Turbo C 2.0. When I run it I get the mes
- |> sage "Null Pointer Assignment". I tried different ways that is using malloc, wi
- |> thout malloc, defining structure as a tag and then declaring an instance, but n
- |> othing helpded. I have 2M RAM on my pc.Anyone has any suggestion send it to
- |> u17868@uicvm..cc.uic.edu
- |>
-
- I'm a bit confused. You say that you want to read from a file, but the code
- seems to try to read from the keyboard and WRITE to the file. Anyway, although
- I can't say for certain what's causing the "Null pointer assignment" message,
- there are enough mistakes in the program anyway, so let's walk through them:
-
- |> #include <stdio.h>
- |> #include <stdlib.h>
- |> struct {
- |> int id;
- |> char date[9];
- |> char day[10];
- |> int stime;
- |> int length;
- |> char location[10];
- |> char with_who[10];
- |> char phone[11];
- |> char subj[10];
- |> char note[10];
- |> int flag;
- |> }temp;
- |>
-
- Turbo C has a maximum size of 64K for a structure. This structure is only 78
- bytes long (a bit more if you turn on word alignment), so that is not the problem.
-
- |> main()
- |> {
- |> int i;
- |> FILE *file_pointer;
- |> file_pointer = fopen("activity.dat","rb+");
-
- This is the only place where you hint at reading instead of writing. You open
- the file for reading AND writing, and this call fails if the file doesn't
- exist. It seems more sensible, given the following instructions, to use mode
- "wb".
-
- |> fseek(file_pointer,0,0);
-
- Completely redundant. The file pointer is already positioned at the beginning
- of the file. But so long as it's there, it seems better to use SEEK_SET as the
- third argument. I'm not certain if the ANSI standard guarantees it to be set
- to 0 or not, but it seems to be the "approved" form of the third argument.
-
- |>
- |> for(i=0;i<=4;i++)
-
- Maybe I'm stating something obvious here, but this loop loops five times, and
- not four. If you really wanted four loops, write for (i=0; i<4; i++)
-
- |> {
- |> scanf("%d",&temp.id);
- |> gets(temp.date);
-
- This is the real big mistake in the program. If you had inserted appropriate
- printf/puts/fputs statements before each statement to prompt for the next
- value, you would have discovered that gets takes its value from the same line
- as the scanf call. scanf skips all preceding whitespace, which includes any
- newline you might hammer in with repeated banging of the RETURN key. It then
- tries to parse the next characters as an integer. If it fails (the user made
- a mistake), scanf returns but leaves the erroneous characters in the input
- buffer to be read by gets.
-
- But even if the user typed the value correctly, there's still a problem. scanf
- returns at the first character that can't be interpreted as an integer, but
- again it leaves the remaining characters unread in the input buffer, which
- includes the newline character. gets will then read the remaining characters
- on the line, instead of the next line as you probably intended. It will do
- this even if you hit RETURN directly after typing the number, in which case
- gets will return with an empty string in temp.date.
-
- This still leaves the problem that gets doesn't know the size of the string
- temp.date, and happily overwrites any memory following it if the string is
- longer than 8 characters. I would say that this is the most likely cause of
- the "Null pointer assignment" message.
-
- |> gets(temp.day);
- |> scanf("%d",&temp.stime);
- |> scanf("%d",&temp.length);
- |> gets(temp.location);
- |> gets(temp.with_who);
- |> gets(temp.phone);
- |> gets(temp.subj);
- |> gets(temp.note);
- |> scanf("%d",&temp.flag);
-
- My notes above still apply. I might add that if one scanf fails, and is
- followed by a new scanf call, the second scanf will read the same characters
- as the first, and so will also fail.
-
- |> fwrite(&temp,sizeof(temp),1,file_pointer);
- |> }
- |> }
- |>
-
- You have no fclose(file_pointer). That is not strictly necessary, though.
-
- Conclusion: Don't use scanf or gets. They both have big problems. scanf has
- no decent facilities for error recovery. gets has no way of checking the size
- of its argument. Though more complicated, I'll suggest that you write wrapper
- functions that read one single line and stores it in a variable, possibly after
- some conversion, which could be done with sscanf, atoi or strtol.
-
- --
- Yngvar F°lling (yngvar@imr.no)
- Institute of Marine Research
- Bergen
- Norway
-