[comp.sys.ibm.pc] Microsoft C - Heap space question

jmn@cbnewsh.ATT.COM (john.b.medamana) (09/06/89)

Is it possible to get a separate physical segment (Group?) 
for heap?   I am using the Microsoft C large memory model.
The default allocation combines stack and heap into a 
single 64K segment (DGROUP).  Is there a way to get a
separate segment for heap?

I'm using Microsoft C 5.1 and Microsoft LINK.

Thanks in advance.

John Medamana
AT&T, Holmdel, NJ
email: att!homxb!arch3!johnm

chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) (09/07/89)

[yuck!]

In article <3631@cbnewsh.ATT.COM> jmn@cbnewsh.ATT.COM (john.b.medamana) writes:
|Is it possible to get a separate physical segment (Group?) 
|for heap?

	Normally? No, I don't believe you can.  However, there is an easy way
to get more heap space--which is what I assume you want.

	MicroSoft, and most other DOS compilers for that matter, provide a
function to allocate heap space using far pointers.  This way, if the heap
requirements exceed 64K, it will grab another chunk of system memory.  The
function is declared--I believe--as "char far *farmalloc(size_t);"  Note the
far pointer, rather than the normal, "near", pointer.  If you are using the
large memory model, there should be no problem--all pointers are converted to
fars and thus all pointers are thirtyt-two instead of sixteen bits wide.  Be
sure to read the rules on using far pointers to understand the differences and
what, if any, code you might have to modify.  In general, make sure you
declare your pointers explicitly far.

	One very important note about farmalloc: usually, it will grab memory
that was not original assigned to the executable when it ran.  Therefore, upon
normal terminal exit (via exit) this memory _will not_ be returned to the
operating system.  To avoid "Insufficent Memory" errors later down the road,
be sure to explicitly free this allocated memory.  I believe farmalloc has a
corresponding free function called farfree, but check for user's guide to be
exact on it's usage.

	Are sixteen bit segmented systems wonderful, or what?

schaut@rt1.cs.wisc.edu (Richard Schaut) (09/07/89)

In article <4143@csd4.csd.uwm.edu> chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) writes:
|[yuck!]
|	MicroSoft, and most other DOS compilers for that matter, provide a
|function to allocate heap space using far pointers.  This way, if the heap
|requirements exceed 64K, it will grab another chunk of system memory.  The
|function is declared--I believe--as "char far *farmalloc(size_t);"  
				      ^^^^
If MS C is ANSI compatible, then the function would be declared as
"void far *farmalloc(size size_t);" thereby removing the need to cast
the return value to a pointer to a specific kind of object.
--
Rick

"Any questions?  Any answers?  Anyone like a mint?" -- source unknown

cb@sequoia.UUCP (Christopher D. Brown) (09/07/89)

In article <3631@cbnewsh.ATT.COM> jmn@cbnewsh.ATT.COM (john.b.medamana) writes:
>Is it possible to get a separate physical segment (Group?) 
>for heap?   I am using the Microsoft C large memory model.
>The default allocation combines stack and heap into a 
>single 64K segment (DGROUP).  Is there a way to get a
>separate segment for heap?
>
>I'm using Microsoft C 5.1 and Microsoft LINK.

MSC 5.1 _fmalloc, which is the large model malloc, allocates new, far
memory until all (MS-DOS) available memory has been allocated;  At this
point _fmalloc calls _nmalloc as a last resort.  Thus, ordinarily,
allocation is not from DGROUP.  Note that DGROUP is at the end of
the load and can be extended by _nmalloc ONLY if the memory above
it has not been allocated via _fmalloc, halloc, or direct calls to
the MS-DOS memory allocation primatives.

The library routines halloc and hfree may be of interest.  They map
directly to the MSDOS memory allocation primatives.

Chris Brown
Net: execu!cb@cs.texas.edu
Voice: (512) 346-4980

gyugyi@portia.Stanford.EDU (Paul Gyugyi) (09/08/89)

Another way to get stack and heap ("near data") to be seperate is the
compiler option /Gt.  Specifying /Gt will place every variable in the near
heap (i.e. things you didn't specify as "far") bigger than some threshold
(default 256bytes) into it's own segment.  When compiling the new version
of NetHack, I had to use /Gt:1 to put all data into seperate segments
because there was more than 64K of chars and ints.  MSC is smart enough
to recombine the million segments this generates into several larger ones,
so efficiency isn't greatly compromise, and everything works fine
without changing the code.
-gyug

dts@quad.uucp (David T. Sandberg) (09/08/89)

In article <2930@puff.cs.wisc.edu> schaut@rt1.cs.wisc.edu (Richard Schaut) writes:
:In article <4143@csd4.csd.uwm.edu> chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) writes:
:|function is declared--I believe--as "char far *farmalloc(size_t);"  
:				      ^^^^
:If MS C is ANSI compatible, then the function would be declared as
:"void far *farmalloc(size size_t);" thereby removing the need to cast
:the return value to a pointer to a specific kind of object.

MSC 5.1 does indeed return void pointers from all of it's malloc calls.
It should be noted that the referred-to function is actually "void far
*_fmalloc(size_t size);", and that when compiling with large model,
malloc() calls are mapped to _fmalloc by default.

-- 
                                  David Sandberg - Quadric Systems
 "As of Friday, August 25, 1989,  PSEUDO: dts@quad.uucp
      Triton is a Placemat."      ACTUAL: ..uunet!rosevax!sialis!quad!dts

kremer@cs.odu.edu (Lloyd Kremer) (09/08/89)

In article <3631@cbnewsh.ATT.COM> jmn@cbnewsh.ATT.COM (john.b.medamana) writes:

>Is it possible to get a separate physical segment (Group?)
>for heap?
>The default allocation combines stack and heap into a
>single 64K segment (DGROUP).


I don't believe you can change the contents of DGROUP without producing
intermediate assembly code, modifying it, and then using the Microsoft Macro
Assembler.  But don't expect any other Microsoft programmer's aids to work on
the resulting executable.

If DGROUP is too crowded, you could reduce stack space (within reason) by
using command line linker options, or use the -Gt compiler option to reduce the
size threshold at which aggregate objects are sent to far data segments.

-- 
					Lloyd Kremer
					...!uunet!xanth!kremer
					Have terminal...will hack!

catone@dsl.cis.upenn.edu (Tony Catone) (09/28/89)

In article <4143@csd4.csd.uwm.edu> chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) writes:
>	One very important note about farmalloc: usually, it will grab memory
>that was not original assigned to the executable when it ran.  Therefore, upon
>normal terminal exit (via exit) this memory _will not_ be returned to the
>operating system.  To avoid "Insufficent Memory" errors later down the road,
>be sure to explicitly free this allocated memory.  I believe farmalloc has a
>corresponding free function called farfree, but check for user's guide to be
>exact on it's usage.

Is this really true?  I thought that DOS automatically allocated all free
system memory (not expanded or extended) to the currently executing program.
At least this is the way it worked when I used the EXEC call from assembly
language in DOS's 2.1 and 3.1; before you could spawn a child process, you 
had to explicitly deallocate memory.  I also believe I just recently saw an
article in the MicroSoft Systems Journal that used this same technique.
Does using C make a difference in this behavior?

- Tony
  catone@dsl.cis.upenn.edu
  catone@wharton.upenn.edu

Ralf.Brown@B.GP.CS.CMU.EDU (09/28/89)

In article <14792@netnews.upenn.edu>, catone@dsl.cis.upenn.edu (Tony Catone) wrote:
 >In article <4143@csd4.csd.uwm.edu> chad@csd4.csd.uwm.edu (D. Chadwick Gibbons) writes:
 >>       One very important note about farmalloc: usually, it will grab memory
 >>that was not original assigned to the executable when it ran.  Therefore, upon
 >
 >Is this really true?  I thought that DOS automatically allocated all free
 >system memory (not expanded or extended) to the currently executing program.

.COM programs always get the largest available block of memory (which is
all free memory unless you've managed to fragment memory by doing
something like running a TSR while shelled out of another program).
.EXEs get the amount of memory requested in their header info, which is
usually specified as FFFFh paragraphs (all available memory), but can be
changed by a utility such as EXEMOD.

 >Does using C make a difference in this behavior?

At least the Turbo C startup code (before main() is reached) adjusts the
program's memory block to use only the required memory, even though it
might initially have been given all of memory.

--
UUCP: {ucbvax,harvard}!cs.cmu.edu!ralf -=-=-=-=- Voice: (412) 268-3053 (school)
ARPA: ralf@cs.cmu.edu  BIT: ralf%cs.cmu.edu@CMUCCVMA  FIDO: Ralf Brown 1:129/46
FAX: available on request                      Disclaimer? I claimed something?
"All through human history, tyrannies have tried to enforce obedience by
 prohibiting disrespect for the symbols of their power.  The swastika is
 only one example of many in recent history."
-- American Bar Association task force on flag burning

scott@bbxsda.UUCP (Scott Amspoker) (09/29/89)

In article <2522052c@ralf> Ralf.Brown@B.GP.CS.CMU.EDU writes:
>In article <14792@netnews.upenn.edu>, catone@dsl.cis.upenn.edu (Tony Catone) wrote:
>.EXEs get the amount of memory requested in their header info, which is
>usually specified as FFFFh paragraphs (all available memory), but can be
>changed by a utility such as EXEMOD.

It is considered good programming practice under DOS to return unneeded
memory to the system when your program starts up.  .COMs typically get
all of memory for historical reasons.  Such programs frequently just assume
they have all of memory.  .EXEs are smarter but, as Tony Catone says,
usually get all of memory anyway.

>At least the Turbo C startup code (before main() is reached) adjusts the
>program's memory block to use only the required memory, even though it
>might initially have been given all of memory.

This is true.  I use Turbo C myself.  I would hope that Microsoft C
also did this since the system() library call wouldn't work.  To 
require the programmer to explicity deallocate memory at startup
would not be consistent with the "spirit of C".

-- 
Scott Amspoker
Basis International, Albuquerque, NM
(505) 345-5232