🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.os.msdos.programmer
Article #2477

Re: malloc() and free() is order important

#2477
From: Joe English Muffin
Date: Tue, 02 Oct 1990 03:01
97 lines
3595 bytes
duvalj@bionette.cgrb.orst.edu (Joe Duval) writes:

>Hi,

>  I am using Turbo C on a 386-20 with 1 Meg of RAM.

Which memory model?  If it's small, tiny, or medium,
that could be part of the problem.

>My question is does the order of mallocing and freeing data matter?  Should
>whatever I malloc first be free'd last or the opposite?  My program is showing
>inconsistency that seems to relate to the malloc'ing and free'ing I am doing.

No; you can free() mallocked areas in any order,
as long as you don't free() the same thing twice.


>Here is how my program "works":

[ ... Much deleted ]

>#define LINEDELTA 100
>#define STRLEN     80

>typedef char element[STRLEN] /* will be a line of a data file, lines can be up
>								to 80 characters long */

>main ()
>{	element	*data1, *data2;
>
>	data1 = (element *) malloc (LINEDELTA*sizeof(element *));
>	data2 = (element *) malloc (LINEDELTA*sizeof(element *));

First, you really should check malloc's return
value.  It just might fail and return NULL.

>  /* One of the files is usually about 20 times the size of the other.  If I
>	 read in the smaller one first, the data in the smaller one gets trashed
>	 when I read in the data to the second one.  What can I do to avoid that.
>	 things are fine if I read in the data for the larger one first (I may
>	 not know which of the two is the larger at run time)
>   */

>	lines1 = fillarray ("test1", data1);
>	lines2 = fillarray ("test2", data2);

I would guess, that since fillarray() [description
deleted] calls realloc() several times, the heap
is probably getting too fragmented to allocate
any more big chunks, and one of the realloc()s
eventually fails.

You could try using an exponentially increasing
realloc() size instead of asking for
(current_size + LINEDELTA) elements each time.
That will decrease the number of realloc()s from
O(n) to O(log n), which will probably help.
Some good choices would be: current_size * 2
(O(2^n)) or current_size + last_size (O(Fib(n))).

As for malloc() in general, here are the rule-of-thumb
guidelines that I use:

+ Never malloc() lots of little items; malloc() off a
  big chunk and hand it out a piece at a time.  If you
  need to free() the items individually, write your
  own free-list manager for each size item.  (Or write
  a general-purpose one; that's what I did.)

  This saves malloc() overhead on each item allocated,
  and reduces fragmentation on many implementations of
  the allocator.

+ If you must malloc() small structures, malloc()
  the big stuff first.

  This helps fragmentation on most implementations of
  the allocator.

+ Don't use realloc() to dynamically resize things;
  use linked-lists or other dynamic structures.

+ If you must realloc(), then realloc() exponentially
  increasing sizes.

  This helps fragmentation on most implementations of
  the allocator.


(Why "on most implementations of the allocator?"
Malloc()/free() can be implemented in several
ways; I have no idea which one Turbo C uses.)


--Joe English

  jeenglis@alcor.usc.edu
Technical Details
Message-ID: <12290@chaph.usc.edu>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!samsung!usc!chaph.usc.edu!alcor.usc.edu!jeenglis
References: <20681@orstcs.CS.ORST.EDU>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!samsung!usc!chaph.usc.edu!alcor.usc.edu!jeenglis
From: jeenglis@alcor.usc.edu (Joe English Muffin)
Newsgroups: comp.os.msdos.programmer
Subject: Re: malloc() and free() is order important
Message-ID: <12290@chaph.usc.edu>
Date: 2 Oct 90 03:01:19 GMT
References: <20681@orstcs.CS.ORST.EDU>
Sender: news@chaph.usc.edu
Distribution: na
Organization: Joe's Homeopathic Hangover Remedies
Lines: 97
Nntp-Posting-Host: alcor.usc.edu