[comp.lang.c] malloc, a temporary variable, and a linked list

duvalj@bionette.cgrb.orst.edu (Joe Duval) (09/18/90)

Hi, 
  I have this segment of code that is trying to read in specified data from 
a text file.  FYI: The data is organized by year and a section number (12/yr).
There may be any number of lines of data for a section in a year (possibly as
many as 70).

I am using Turbo C but this doesn't contain anything specific to TC.

The segment must read in the data for all years that corresponds to that
section number.  The code is specific to my application and I tried to make
it clear what I was trying to do.

What I really want to know is what happens to the variable temp each time it
is malloced?  Does it end up taking up a whole lot of memory or does the
earlier malloced memory get lost?  How would I free this?

I doubt this is the cleanest way of obtaining this data.  And there may be
a better way.  I don't want flames, but some advice would help.  I have
included a small portion of the data file after the code.


Here it is:
*******************************  Beginning of code segment
/* various includes */

#define STRLEN 80

/* a linked list to hold the data for one year */
struct linelist {
	char	line[STRLEN-20];
	struct linelist *next;
	};

typedef struct linelist		linelist;

/* a year and its attached data */
typedef struct {
	char 	date[7];
	linelist *points;
	} data;

FILE  *infile;

/* an array of data for each year */
data indata[MAXYRS];

int FillInData (FILE *infile, int xsecnum)
/****************************************************
	this function should read in the data from infile and place the data into
	the global variable "indata."  The xsecnum variable is the section number
	to search for in each year's data.  The indata structure will hold the
	date and then a linked list of the data for that year
*****************************************************/
{   linelist	*temp;   /* temporary linked list */
	char 		buffer[STRLEN-20];  /* buffer for file input */
	int 		lines = 0,
				xsnumber;

	while (!feof(infile)) {
	/* read in a line of data and test if the section number matches the
	 * section number we are analyzing
	 */
		fgets (buffer, STRLEN, infile);
		sscanf (buffer + 24, "%3d", &xsnumber); 
		if (xsecnum == xsnumber) {

		/* we are now at the beginning of the data for xsecnum for the 
		 *  next year
		 */
			strncpy (indata[lines].date, buffer+17, 6);
			indata[lines].date[6] = '\0';

		/* Since we are in a loop, what happens to temp on the second and 
		 * later passes through this loop?  Should I free it before I come
		 * back to this loop?
		 */
			temp = (linelist *) malloc (sizeof(linelist));
			indata[lines].points = temp;  /* retain the top of the list */

		/* Now while the date stays the same, the section number stays the same
		 * and it is not the end of the file, add the new line to the linked
		 * list.
		 */
			while ((strncmp (buffer + 17, indata[lines].date, 6) == 0) &&
					!feof(infile) && xsecnum == xsnumber) {
				strcpy (temp->line, buffer);
				fgets (buffer, STRLEN, infile);
				sscanf (buffer + 24, "%3d", &xsnumber);
				if ((temp->next = (linelist *) malloc (sizeof (linelist))) == NULL)
					perror ("FillInData");
				temp = temp->next;
				}
		/* We are done with another year's data, increment the lines (years)
		 * counter and move on
		 */
			strcpy (temp->line, "\0");
			temp->next = NULL;
			lines++;
			}
		}
	return lines;
}

*******************************  End of code segment

*******************************  Begin Portion of data file
			     (date) (sec#)
GS024 HJAMAC     780414   1     169     150     169 LI
GS024 HJAMAC     780414   1     169     400     213 LI
GS024 HJAMAC     780414   1     169     500     242 LI
GS024 HJAMAC     780414   1     169    1950     181 LI
.
.
.
GS024 HJAMAC     780414   2     137     185     196 LI
GS024 HJAMAC     780414   2     137     265     252 CB
GS024 HJAMAC     780414   2     137     342     277 CB
GS024 HJAMAC     780414   2     137     380     285 CB

GS024 HJAMAC     800710   1     135       0     135 LI
GS024 HJAMAC     800710   1     135      50     154 LI
.
.
.
*******************************  End Portion of data file

This turned out to be pretty long, thanks for reading.
I appreciate any help.
Thanks.
-Joe
--
Joe Duval		duvalj@bionette.cgrb.orst.edu
Losing your temper generally represents the incipient stage of rectal-
cranial inversion.

wallace@ynotme.enet.dec.com (Ray Wallace) (09/20/90)

In article <20319@orstcs.CS.ORST.EDU>, duvalj@bionette.cgrb.orst.edu (Joe Duval) writes...
>What I really want to know is what happens to the variable temp each time it
>is malloced?  Does it end up taking up a whole lot of memory or does the
>earlier malloced memory get lost?  How would I free this?

>			temp = (linelist *) malloc (sizeof(linelist));
>			indata[lines].points = temp;  /* retain the top of the list */

You don't want to free the memory that temp is pointing too. The memory is
being used to create your list, via indata[lines].points and
indata[lines].points->next which keep track of the malloc'ed address'.

If at some point you are done using the data from one or all of the lists
pointed to by indata[], then you could walk through each of the lists
(backwards) and free the memory.

---
Ray Wallace		
		(INTERNET,UUCP) wallace@oldtmr.enet.dec.com
		(UUCP)		...!decwrl!oldtmr.enet!wallace
		(INTERNET)	wallace%oldtmr.enet@decwrl.dec.com
---