*BSD News Article 34222


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!msuinfo!netnews.upenn.edu!news.amherst.edu!news.mtholyoke.edu!uhog.mit.edu!europa.eng.gtefsd.com!howland.reston.ans.net!EU.net!Germany.EU.net!netmbx.de!zelator!deadline.bln.sub.org!boavista.panic.bln.sub.org!boavista.bln.sub.org!erdmann
From: erdmann@boavista.bln.sub.org (Michael Erdmann)
Newsgroups: comp.os.386bsd.development
Subject: Best buffering method for gets, read1line etc...
Date: 11 Aug 1994 12:26:14 GMT
Organization: none
Lines: 62
Distribution: world
Message-ID: <32d5d7$27j@boavista.bln.sub.org>
Reply-To: erdmann@boavista.bln.sub.org (Michael Erdmann)
NNTP-Posting-Host: 200.0.0.1
Keywords: realloc

First of all sorry for changing the title, but i think this issue is not 
connected to the original problem:

 Why does FreeBSD 1.1.5 say gets() is unsafe?

After all the discussion i will use the following code given below
as a replacement of gets:

Based Kees J. Bot code original code with following changes:

1. An intermediate buffer is allocated for the whole liftime of the 
   application. This buffer will be increased by the rule

	size =  _reallocTuning *size

   (In my original positing i have used size += size in contradiction
   to the text, did any body   realize this??).


2. The function returns a string of the exact size. So no memory is
   wasted by giving to large strings back to the application.


Still the major performance bottleneck beside of i/o speed is the 
strdup which yields the return string. The allocation/reallocation 
method will not be the important issue for well structured text files, 
because the realloc will not happen on every line. The worst case would be 
an document with constantly increases line length.

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>

double _reallocTuning = 1.5; 
#define K  *1024

char *read1line(FILE *fp)
{
	static char *line = NULL;
        size_t  lineLength=2 K;
	size_t idx;
	int c;

        if( line ==NULL )
	   line = malloc(lineLength*sizeof(char));
        
	for(idx=0; (c= getc(fp)) != EOF && c != '\n'; ++idx) {
	    if (idx == lineLength ) {
		lineLength = _reallocTuning * lineLength ;
		line= realloc(line, lineLength*sizeof(char));
	    }
	    line[idx]= c;
	}
	if (c == EOF) 
	    return NULL;

	line[idx]= 0;

	return strdup(line);
}

--