[comp.sys.mac.programmer] malloc

ray@hydroplane.cis.ohio-state.edu (william c ray) (11/06/89)

Probably another stupid question, but here goes... I've been trying to 
convert some lightspeed C (3.02) projects over to Think 4.0, and keep getting
the same problem.  Mallocs that used to work just fine, are returning
out-of-memory.  The same thing happens with calloc, etc.  Is this a known
4.0 bug?  is there a fix for it?  I can manage to allocate maybe 50 bytes
before I get a  Null...  Anyone have any ideas?

Thanks,
(Just a stupid pascal programmer hacking away)
Will Ray

mm5l+@andrew.cmu.edu (Matthew Mashyna) (11/06/89)

I had lots of unpredictable memory and string problems with Think C
until I included stdlib.h, stdio.h and string.h. It would be nice if TC
spit up on standard library call prototyping the way MPW does. MPW's
pickiness prevents a lot of problems for me.




Matt Mashyna
Macintosh Initiative,
H&SS Dean's Office
Carnegie Mellon

siegel@endor.harvard.edu (Rich Siegel) (11/07/89)

In article <IZJO8mO00iLOQ1u19n@andrew.cmu.edu> mm5l+@andrew.cmu.edu (Matthew Mashyna) writes:
>I had lots of unpredictable memory and string problems with Think C
>until I included stdlib.h, stdio.h and string.h. It would be nice if TC
>spit up on standard library call prototyping the way MPW does. MPW's
>pickiness prevents a lot of problems for me.
>
	Try turning on "Require Prototypes" in the Options... dialog.

	(User's Guide, page 129.)

R.

~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

"There is no personal problem which cannot be solved by sufficient
application of high explosives."

~~~~~~~~~~~~~~~

rsfinn@athena.mit.edu (Russell S. Finn) (11/10/89)

In article <73658@tut.cis.ohio-state.edu> william c ray <ray@cis.ohio-state.edu> writes:
>Probably another stupid question, but here goes... I've been trying to 
>convert some lightspeed C (3.02) projects over to Think 4.0, and keep getting
>the same problem.  Mallocs that used to work just fine, are returning
>out-of-memory.  The same thing happens with calloc, etc.  Is this a known
>4.0 bug?  is there a fix for it?  I can manage to allocate maybe 50 bytes
>before I get a  Null...  Anyone have any ideas?

THINK C 4.0 now follows the ANSI rules for libraries, and one of the
things that changed is that malloc et al. now take an argument of type
size_t, not int.  Under THINK C 4.0 size_t is a long.  I trust the
problem is now obvious.  Including the appropriate header file
(stdlib.h?) will help find problems like these, since it should
contain prototypes for the functions in question.

-- Russ

ar4@sage.cc.purdue.edu (Piper Keairnes) (03/23/90)

   Well the last time this discussion was around, I didn't know that the
heck these two functions meant (or how C worked for that matter). Things have
changed, but I believe I'm running into the same problem that others did:

   I CAN do the following successfully:

	int  *i;

	i = (int*) malloc(sizeof(int) * 5);

   but if CANNOT do the following:

	int *i;

	i = (int*) malloc(sizeof(int) * 6);

   Notice the difference??? Trying to allocate 5 gives me a valid pointer.
Trying to allocate 6 gives me 0x000000. the big NULL! Anyways, anyone know
why this is happening? I'm on a 2.5meg SE (don't believe a lack of memory
to be the problem).

-----
Piper Keairnes
ar4@sage.cc.purdue.edu

sdh@flash.bellcore.com (Stephen D Hawley) (03/24/90)

In article <3860@sage.cc.purdue.edu> ar4@sage.cc.purdue.edu (Piper Keairnes) writes:
>   Well the last time this discussion was around, I didn't know that the
>heck these two functions meant (or how C worked for that matter). Things have
>changed, but I believe I'm running into the same problem that others did:
>
>   I CAN do the following successfully:
>
>	int  *i;
>
>	i = (int*) malloc(sizeof(int) * 5);
>
>   but if CANNOT do the following:
>
>	int *i;
>
>	i = (int*) malloc(sizeof(int) * 6);
>
>   Notice the difference??? Trying to allocate 5 gives me a valid pointer.
>Trying to allocate 6 gives me 0x000000. the big NULL! Anyways, anyone know
>why this is happening? I'm on a 2.5meg SE (don't believe a lack of memory
>to be the problem).

Handy hints:

	Use NewPtr() to get memory if you're doing Mac-only stuff.  Think
		C will promote shorts to longs on tollbox calls, so you
		don't have to worry about the argument.

	malloc() takes as its argument type size_t which is an unsigned
		long.  sizeof() evaluates to a short, thus unless you
		#include stdlib.h, you will be sending malloc the wrong
		size.  Try instead i = (int *)malloc(sizeof(int) * 6L);
		or i = (int *)malloc((long)(sizeof(int) * 6));

Steve Hawley
sdh@flash.bellcore.com

"I'm sick and tired of being told that ordinary decent people are fed up with
being sick and tired.  I know I'm certainly not, and I'm sick and tired of
being told that I am."

rcfische@polyslo.CalPoly.EDU (Raymond C. Fischer) (03/24/90)

In article <3860@sage.cc.purdue.edu> ar4@sage.cc.purdue.edu (Piper Keairnes) writes:
>
>   Well the last time this discussion was around, I didn't know that the
>heck these two functions meant (or how C worked for that matter). Things have
>changed, but I believe I'm running into the same problem that others did:
>
>   but if CANNOT do the following:
>
>	int *i;
>
>	i = (int*) malloc(sizeof(int) * 6);

Try using the include file that defines malloc, or using the following call ...
	i = (int *) malloc ((long)(sizeof(int) * 6));

malloc expects a long, and if you don't specify this somehow, the expression
for the size will probably evaluate to an int.  You'll be left with extra
non-useful stuff on the stack being interpreted as a size.

Ray Fischer
rcfische@polyslo.calpoly.edu

adiseker@potomac.ads.com (Andrew Diseker) (07/28/90)

	Anyone using the new (4.0 and later) malloc() and free() should be
aware of a potential loss of memory.  Apparently, for the change from 3.0 to 
4.0, the Symantec folks changed the implementation of the ANSI memory routines.
Malloc() and calloc() now only call NewPtr if the memory needed is larger than
15000 bytes.  If the memory needed is smaller, the library will try to find
some 'free' space in an internal linked list of 15000 byte blocks.  This is a
good idea in some respects, since NewPtr calls for 12 bytes, say, is very
expensive, and if the linked list doesn't have the unused space available, it
just has to NewPtr(15000) every so often.  
	The problem we ran into WRT the new method is this: the free() 
function _does not_ mark unused blocks, and the linked list is not compacted 
unless you call realloc() on the pointer!  Not only that, even if space were 
'free'd correctly, any 15000 byte blocks that had no 'allocated' pointers in
them are never DisposPtr'd!  The bottom line is that if you try to do what we 
did in our project, that is, malloc() and free() thousands of 12-64 byte 
objects over and over, you eventually run out of memory.  
	I mailed Rich Seigel telling him what we had found, and he replied 
that, yes, that is the way Symantec intended for the package to work, and if 
we wanted something better, we would have to write it ourselves.  This seemed 
fair enough, since Symantec was kind enough to supply their libraries' source 
code.  However, he never mentioned the bug with free().  Maybe someone who
knows 680x0 assembler could set me straight on that.  
	Anyway, we went back and modified the 3.0 version, fixing a realloc()
bug we found ( is ANSI non-compliance truly a bug? ), and redesigned part of
our code to reduce the number of malloc calls ( can you say hard-coded arrays?
Sure you can! ).  If anyone is interested, I may be able to let them have a 
copy of our allocation routines.

----
Andrew Diseker                            ( )-( )   Mouse-Tested!
Advanced Decision Systems                  /o o\    Hacker-Approved!
UUCP: sun!sundc!potomac!adiseker          / =v= \ ,--_
Internet:  adiseker@potomac.ads.com       ;;---;;     `--'
-- 
Andrew Diseker                            ( )-( )   Mouse-Tested!
Advanced Decision Systems                  /o o\    Hacker-Approved!
UUCP: sun!sundc!potomac!adiseker          / =v= \ ,--_
Internet:  adiseker@potomac.ads.com       ;;---;;     `--'

usenet@nlm.nih.gov (usenet news poster) (01/24/91)

	Is there an idiosyncracy about malloc() in THink C on the Mac.
Is there an idiosyncracy about this on the Mac.

I have code that compiles and runs under Unix and MSDOS.  On the Mac,
it compiles without error and runs most of the time, however calls
to malloc(() which on the other operating systems return a pointer
and space reture null on the Macintosh (using the Think C console.h
and ANSI libraries).

hanche@imf.unit.no (Harald Hanche-Olsen) (01/25/91)

In article <1991Jan24.060336.12684@nlm.nih.gov> usenet@nlm.nih.gov (usenet news poster) writes:

   I have code that compiles and runs under Unix and MSDOS.  On the Mac,
   it compiles without error and runs most of the time, however calls
   to malloc(() which on the other operating systems return a pointer
   and space reture null on the Macintosh (using the Think C console.h
   and ANSI libraries).

You probably asked for more memory than is available.  (Always have
your program check for a NULL return from malloc(), right?)  If you
need to ask for large chunks of memory, try increasing your
application's multifinder partition size.

Did you remember to #include <stdlib.h>?  If not, you may have a
long/short type conflict in the arguments to malloc...

- Harald Hanche-Olsen <hanche@imf.unit.no>
  Division of Mathematical Sciences
  The Norwegian Institute of Technology
  N-7034 Trondheim, NORWAY

ldg@drywit.ATT.COM (XGPB30000-GibbonsD(DRR6702)262) (01/25/91)

From article <1991Jan24.060336.12684@nlm.nih.gov>, by usenet@nlm.nih.gov (usenet news poster):
> 
> 	Is there an idiosyncracy about malloc() in THink C on the Mac.
> Is there an idiosyncracy about this on the Mac.
> 
> I have code that compiles and runs under Unix and MSDOS.  On the Mac,
> it compiles without error and runs most of the time, however calls
> to malloc(() which on the other operating systems return a pointer
> and space reture null on the Macintosh (using the Think C console.h
> and ANSI libraries).

I have Think C 3.0, and I get caught by this one every time.
Make sure the value you're passing to malloc() is an int (16 bits)
and not a long. There is another routine (mlalloc ?) which
takes a long.


--
--------------------------------------------------------------------------------
-- Doug Gibbons			| ldg@druhi.ATT.COM or att!druhi!ldg
-- AT&T Bell Laboratories 
-- Denver CO

eswu@engshien.austin.ibm.com (Eng-Shien Wu) (01/26/91)

[In article 12426, werner@bio.NLM.NIH.GOV (Craig Werner)
 asks why he gets NULL when he calls malloc() in THINK C.]

The problem lies in the THINK C libraries. In their
implementation of malloc, they have an if-test to see
if you are allocating more than 16K of memory. If so,
it just returns NULL with no check of available system
resources. [Pretty arbitrary. Also, this restriction is
not mentioned in their docs. Fortunately, they supply
source code to their libraries.]

I've been using NewPtr() and NewHandle() instead of malloc().
Does any ``real'' Mac programmer know what we are really
suppose to use, especially for programs that really beat on
garbage collectors? 


-- Eng-Shien Wu,  "My views only, does not represent IBM's"

	X Windows, IBM Advanced Workstations Div, Austin, Texas
	Internet: eswu@ub.cc.umich.edu    VNET: ausvmq(engshien)

jmunkki@hila.hut.fi (Juri Munkki) (01/27/91)

In article <4978@awdprime.UUCP> eswu@ub.cc.umich.edu writes:
>I've been using NewPtr() and NewHandle() instead of malloc().
>Does any ``real'' Mac programmer know what we are really
>suppose to use, especially for programs that really beat on
>garbage collectors? 

I think we are supposed to avoid allocating a lot of handles
and pointers with the memory manager. If a program I'm writing
requires more than a few allocated blocks, I always write my
own memory management routines. Usually I allocate one or two
handles and resize them in chunks.

For example, Dizzy, a digital circuit simulator, uses a single
NewHandle and then uses ResizeHandle to allocate memory in
blocks of 32KB. I have my own garbage collection routines
and a routine that allocates memory from this "heap".

I try to avoid locking. Most of the time the handles I allocate
just float there. All references to these structures are defined
as offsets from the beginning of the block or handle-like with
my own (unlocked) "master pointer block" (allocated as a handle).

I have never noticed any delays caused by memory allocation in
this way. The only way to make Dizzy slow is to make the chunk
size really small (using 64 bytes usually does the trick). The
chunk size I use is never hard-coded, so I can modify it to be
really small, if I want to track down memory allocation bugs.

The terminal program I'm using right now has a buffer for lines
that scroll offscreen. That buffer is now set to 2500 lines and
the allocation block size is 8192 bytes. The program does garbage
collection on this structure, if more than 16384 bytes are wasted.
So far, I've never noticed any pauses because of memory management.

I never use malloc on a native Macintosh program and I use NewPtr
only to reserve memory for the whole lifetime of the program.
(You could probably find a few NewPtrs that allocate temporary
memory inside a subroutine, but using a NewHandle and a HLock
would actually be faster, since the memory is not allocated
from the bottom of the heap.)

Luckily for programmers, desk accessories no longer wreck havoc on our
memory management schemes, if the program is running under multifinder.
FKEYs and trap patches can still manage to foil even the best efforts.

   ____________________________________________________________________________
  / Juri Munkki	    /  Helsinki University of Technology   /  Wind  / Project /
 / jmunkki@hut.fi  /  Computing Center Macintosh Support  /  Surf  /  STORM  /
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Chris.Gehlker@p12.f56.n114.z1.fidonet.org (Chris Gehlker) (01/28/91)

EW> I've been using NewPtr() and NewHandle() instead of malloc(). 
EW> Does any ``real'' Mac programmer know what we are really suppose 
EW> to use, especially for programs that really beat on garbage collectors?


I NEVER use malloc().
 
--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!56.12!Chris.Gehlker
Internet: Chris.Gehlker@p12.f56.n114.z1.fidonet.org

adiseker@ADS.COM (Andrew Diseker) (01/28/91)

In article <4978@awdprime.UUCP> eswu@ub.cc.umich.edu writes:
>
>[In article 12426, werner@bio.NLM.NIH.GOV (Craig Werner)
> asks why he gets NULL when he calls malloc() in THINK C.]
>
>The problem lies in the THINK C libraries. In their
>implementation of malloc, they have an if-test to see
>if you are allocating more than 16K of memory. If so,
>it just returns NULL with no check of available system
>resources. [Pretty arbitrary. Also, this restriction is
>not mentioned in their docs. Fortunately, they supply
>source code to their libraries.]
>
>

	I'm sure Rich Siegel will be sure to correct my correction 8),
but here's the scoop.  The above paragraph is not entirely true.  The 
(re,m,c)alloc() code in ThinkC 4.0 is implemented such that requested
allocations of more than 15000 bytes are handled by NewPtr().  Blocks
less than 15000 are "allocated" from a linked list of NewPtr'd blocks
of 15000 bytes.  If there is a "free" space in a block of more than the
requested size, the offset to the space is added to the block's ptr, and
the result is returned.  The problem with the scheme is that "garbage" 
is not collected.  The free() call doesn't actually free space, such 
that 15000byte blocks that have no "allocated" spaces in them are never
DisposPtr'd.  Eventually, your application will run out of memory, if
it runs long enough.  I found a bug in free() anyway that doesn't seem 
to mark the "freed" memory in the block, so that blocks don't even get 
re-used often enough.  I went back to the 3.0 version of alloc.c, and
made the mods to the calling sequences etc. that made them ANSI compliant,
( at least ThinkC 4.0 compliant 8^).  This version calls NewPtr and
DisposPtr for every (*)alloc and free, thus it's slower, but more robust.
E-mail me for a copy, if you'd like one.



>-- Eng-Shien Wu,  "My views only, does not represent IBM's"
>
>	X Windows, IBM Advanced Workstations Div, Austin, Texas
>	Internet: eswu@ub.cc.umich.edu    VNET: ausvmq(engshien)


--
Andrew Diseker                            ( )-( )   Mouse-Tested!
Advanced Decision Systems                  /o o\    Hacker-Approved!
UUCP: sun!sundc!potomac!adiseker          / =v= \ ,--_
Internet:  adiseker@potomac.ads.com       ;;---;;     `--'

siegel@endor.uucp (Rich Siegel) (01/28/91)

In article <J99^_Z&@ads.com> adiseker@ADS.COM (Andrew Diseker) writes:
>In article <4978@awdprime.UUCP> eswu@ub.cc.umich.edu writes:
>>
>>[In article 12426, werner@bio.NLM.NIH.GOV (Craig Werner)
>> asks why he gets NULL when he calls malloc() in THINK C.]
>>
>>The problem lies in the THINK C libraries. In their
>>implementation of malloc, they have an if-test to see
>>if you are allocating more than 16K of memory. If so,
>>it just returns NULL with no check of available system
>>resources. [Pretty arbitrary. Also, this restriction is
>>not mentioned in their docs. Fortunately, they supply
>>source code to their libraries.]
>>
>>
        You're confusing the compare against "maxSize" with the compare
against "MAXSIZ". "maxSize" is a Memory Manager constant (defined in
<MemoryMgr.h>):

#define maxSize 0x80000000

        The storage allocator manages its heap in chunks of 15000 bytes,
and any request larger than a chunk will be managed directly via the
Memory Manager.

If malloc() is returning NIL, it may have been incorrectly prototyped
(or not prototyped at all), or the argument may have been specified 
incorrectly; if the argument to malloc() is the result of an integer
multiplication, one of the operands should be cast to (long) to
avoid integer overflow.

R.



 Rich Siegel	Symantec Languages Group  Internet: siegel@endor.harvard.edu

"...she's dressed in yellow, she says 'Hello, come sit next to me, you
fine fellow..."

time@tbomb.ice.com (Tim Endres) (01/28/91)

In article <665.27A42DD4@stjhmc.fidonet.org>, Chris.Gehlker@p12.f56.n114.z1.fidonet.org (Chris Gehlker) writes:
> EW> I've been using NewPtr() and NewHandle() instead of malloc(). 
> EW> Does any ``real'' Mac programmer know what we are really suppose 
> EW> to use, especially for programs that really beat on garbage collectors?
> 
> I NEVER use malloc().
>  

Using NewPtr() to allocate hundreds of 8 byte objects is not very
efficient on the Macintosh. This may not make any difference on your
weekend programming project, but for commercial or other serious work,
it is a real problem.

We have a version of malloc written here at ICE specifically for the
Macintosh. It is really nice and uses "pools" allowing me to separate
the areas in which memory is allocated. This also solves "leak" problems,
as I can allocate "leaky" objects in one specific pool, then at some
predetermined time free the entire pool and not worry about freeing
individual objects!

We are considering posting this code to the net. Anyone interested?
If so, it will take time to document the code and clean it up for
release, so it won't happen soon, but it won't happen at all if there
is little interest.

tim.

-------------------------------------------------------------
Tim Endres                |  time@ice.com
ICE Engineering           |  uupsi!ice.com!time
8840 Main Street          |  Voice            FAX
Whitmore Lake MI. 48189   |  (313) 449 8288   (313) 449 9208

time@tbomb.ice.com (Tim Endres) (01/30/91)

OK.
You can stop sending the requests. Silly me, I should know better by now.
I will hopefully get the sources posted in the next two weeks.

tim.

-------------------------------------------------------------
Tim Endres                |  time@ice.com
ICE Engineering           |  uupsi!ice.com!time
8840 Main Street          |  Voice            FAX
Whitmore Lake MI. 48189   |  (313) 449 8288   (313) 449 9208

pas@unhd.unh.edu (Paul A. Sand) (01/30/91)

In article <7335@drutx.ATT.COM> ldg@drywit.ATT.COM writes:

>I have Think C 3.0, and I get caught by this one every time.
>Make sure the value you're passing to malloc() is an int (16 bits)
>and not a long. There is another routine (mlalloc ?) which
>takes a long.

Think C 4.0.x's malloc() has more standard behavior than 3.0's: it
expects a size_t (unsigned long) type argument.  Of course, it's
slightly trickier to pass an unsigned long than an int.

It's made even trickier by Think's NON-standard sizeof operator,
which returns type int (signed, of course), even in 4.0.x. Grrr.
(Now, really, how hard would it have been to fix this?)

Moral: protoype that sucker with the line:

#include <stdlib.h>

at the top of any file that has calls to malloc().
-- 
-- Paul A. Sand                |
-- University of New Hampshire | I ain't here on business, baby.
-- uunet!unhd!pas              | I'm only here for fun.
-- pas@unhd.unh.edu            |

bruce@logic.dsg.ti.com (Bruce Florman (BFLM)) (02/02/91)

In article <1CE00001.m1ny6l@tbomb.ice.com> time@ice.com writes:
>
>We have a version of malloc written here at ICE specifically for the
>Macintosh. It is really nice and uses "pools" allowing me to separate
>the areas in which memory is allocated. This also solves "leak" problems,
>as I can allocate "leaky" objects in one specific pool, then at some
>predetermined time free the entire pool and not worry about freeing
>individual objects!
>
>We are considering posting this code to the net. Anyone interested?
>If so, it will take time to document the code and clean it up for
>release, so it won't happen soon, but it won't happen at all if there
>is little interest.
>
>tim.
>

I would be very much interested in seeing your code.  I've recently been
writing a number of C tools, including a memory allocation module, and I'm
always eager to see how others approach the same problems.

I've rolled my own allocater in order to integrate an exception handling
module that I've been working on for awhile: if the allocation request can't
be satisfied with the available memory, an exception is raised, throwing
control back to the most recently activated handler.  This frees the 
programmer from having to clutter his or her code with a lot of error checks,
since if the allocation call returns at all, it has successfully filled the
request.

My exception handling module is probably also a good candidate for posting,
is there any interest out there?  It currently has compile-time conditionals
which allow it to be compiled in THINK C or MPW for the Mac, or in GNU C on
the TI 1500 (and probably any other 680x0 based machine, but I don't have any
others to try it on).

>-------------------------------------------------------------
>Tim Endres                |  time@ice.com
>ICE Engineering           |  uupsi!ice.com!time
>8840 Main Street          |  Voice            FAX
>Whitmore Lake MI. 48189   |  (313) 449 8288   (313) 449 9208

--Bruce Florman
  florman@itg.ti.com

CXT105@psuvm.psu.edu (Christopher Tate) (02/04/91)

In article <1CE00001.m1ny6l@tbomb.ice.com>, time@tbomb.ice.com (Tim Endres)
says:

>Using NewPtr() to allocate hundreds of 8 byte objects is not very
>efficient on the Macintosh. This may not make any difference on your
>weekend programming project, but for commercial or other serious work,
>it is a real problem.
>
>We have a version of malloc written here at ICE specifically for the
>Macintosh. It is really nice and uses "pools" allowing me to separate
>the areas in which memory is allocated. This also solves "leak" problems,
>as I can allocate "leaky" objects in one specific pool, then at some
>predetermined time free the entire pool and not worry about freeing
>individual objects!
>
>We are considering posting this code to the net. Anyone interested?
>If so, it will take time to document the code and clean it up for
>release, so it won't happen soon, but it won't happen at all if there
>is little interest.

Post it!  Post It!  POST IT!  ***POST IT*** !!!!!!!!!!!!

-------
Christopher Tate                   |
                                   |      In space, no one can
cxt105@psuvm.psu.edu               |         hear you sneeze.
{...}!psuvax1!psuvm.bitnet!cxt105  |
cxt105@psuvm.bitnet                |

kevin@crash.cts.com (Kevin Hill) (02/06/91)

In <15828@milton.u.washington.edu> bose@milton.u.washington.edu (Rob Olsen) writes:

>For some reason, I have trouble using malloc() in THINK C.
>Here is an example:
>doit(num)
>int num;
>{
>   char *back;

>   back=malloc(num);
>}
  Try including In your file #include <storage.h>  & #include <memoryMgr.h>
I had the same problem a while ago and that solved it..  Write back
if that does not work as I was having problems with malloc a while ago
and asked the net about it.
  Also, look for the Frequently asked Question file as it goes over a lot
of the basics...
  Feel free to ask though, as I feel that I know a lot about memory allocation
via malloc or NewPtr because I just spent about 2 weeks trying to get the
darn things to work the way I wanted on My Mac!
 Good luck, Kevin
-- 
*******************************************************************************
*  Kevin Hill
*  San Diego State University, Accounting Major.
*  No matter where you go, there you are.
*******************************************************************************
*               \
*         *=====+)---------------------------
*               / 
*  San Diego State Fencing
*******************************************************************************

rg2c+@andrew.cmu.edu (Robert Nelson Gasch) (02/07/91)

>For some reason, I have trouble using malloc() in THINK C.
>Here is an example:
>doit(num)
>int num;
>{
>   char *back;
>
>   back=malloc(num);
>}
>If you know what is wrong with the code PLEASE E-mail me and tell me what
>I need to fix.  Thank you.

Your call to malloc() can't work because the syntax is wrong. You have to
specify the type of pointer you wish to create. Example.

    back = (char *) malloc (num);

If you want to malloc() memory for a structure, you'd use the sizeof() function
Example:

    back = (struct_name *) malloc (sizeof (struct_name));

Hope this helps --> Rob

phils@chaos.cs.brandeis.edu (Phil Shapiro) (02/07/91)

In article <7442@crash.cts.com> kevin@crash.cts.com (Kevin Hill) writes:
   In <15828@milton.u.washington.edu> bose@milton.u.washington.edu (Rob Olsen) writes:
   >For some reason, I have trouble using malloc() in THINK C.
   >Here is an example:
   >doit(num)
   >int num;
   >{
   >   char *back;

   >   back=malloc(num);
   >}
   Try including In your file #include <storage.h>  & #include <memoryMgr.h>

This solution applies only to verion 3.0x of THINK C.  In the newer
version (v4.0x) you will want to #include <stdlib.h>.  The names were
changed to provide better ANSI conformance.

	-phil
--
   Phil Shapiro                           Technical Support Analyst
   Language Products Group                     Symantec Corporation
		Internet: phils@chaos.cs.brandeis.edu

bruce@logic.dsg.ti.com (Bruce Florman (BFLM)) (02/09/91)

In some previous article, someone writes:

>>For some reason, I have trouble using malloc() in THINK C.
>>Here is an example:
>>doit(num)
>>int num;
>>{
>>   char *back;
>>
>>   back=malloc(num);
>>}
>>If you know what is wrong with the code PLEASE E-mail me and tell me what
>>I need to fix.  Thank you.

In article <wbg=xE600WBK82RZZG@andrew.cmu.edu> rg2c+@andrew.cmu.edu replys:
>
>Your call to malloc() can't work because the syntax is wrong. You have to
>specify the type of pointer you wish to create. Example.
>
>    back = (char *) malloc (num);
>
>If you want to malloc() memory for a structure, you'd use the sizeof() function
>Example:
>
>    back = (struct_name *) malloc (sizeof (struct_name));

Since I (and others I'm sure) had just answered this same question via email
a few days earlier, I chose to let someone else handle this one.  But since
the first posted reply isn't correct, I'll answer one more time.

Unlike many C compilers, Think C implements 16-bit ints instead of 32-bit
ints.  Compiler writers are allowed to do this because K&R and ANSI state
only that int is the "natural size of integers on the host machine."  Since
the MC68000 has a 16-bit data bus, so 16 bits may be moved more quickly 
than 32 bits, and since the Macintosh ROM was written to use Lisa Pascal's
16-bit Integer type, the writer(s) of the Think compiler chose 16 bits as
the size of int.  The writers of the MPW C compiler (and the Aztec compiler
and the compilers available on most 680x0 based Unix boxes) chose to 
implement 32-bit ints because the MC68020 and beyond all have 32-bit data
busses, and because it avoids the problems encountered by sloppy programmers
who assume that sizeof(int) == sizeof(char *).  :-)

The malloc call fails because malloc hasn't been prototyped.  Without a 
declaration, the compiler assumes that malloc is a function returning int.
Dispite the fact that malloc generates a full 32-bit pointer value, the 
compiler only knows to take 16 bits of it, so upper half of the address
is stripped off.  Then, since the int is being assigned to a pointer
variable, the 16-bit value is being sign-extended into 32 bits.  This 
process usually (but not always) results is a completely nonsensical 
pointer value.  The cast suggested by the first respondent doesn't change
this at all, since it simply tells the compiler to convert an int into a
pointer, which is what it was going to do anyway.

The malloc call in the above example fails at another point as well.  The 
malloc function expects an argument of type size_t, but an int is being
passed.  Without a prototype, the compiler doesn't know to coerce the 
16-bit argument into 32 bits, so while only two bytes are being pushed onto 
the stack, the malloc function itself is looking at a four byte argument.  
Since the upper two bytes of this argument are what was passed, and the 
lower two bytes are something else entirely, malloc thinks that a HUGE block
is being requested (at least 65,536 times larger than what was intended).
Unless num was a very small number, the request probably can't be satisfied,
so malloc will return NULL in this case.  Even if malloc had been declared
with an "extern char *malloc();" declaration, without a prototype, and 
without a cast like "(size_t)num", the malloc call will fail.

The bottom line of all this is that you should ALWAYS "#include <stdlib.h>" 
in any file which uses malloc and its kin.

Now a note to Rich Siegal and the other folks at Symantec:
  Since this question arises on an almost weekly basis, why don't you folks
include a caveat IN BIG BOLD LETTERS on the malloc page of the _Standard
Libraries Reference_ which explains this common pratfall?  It would make the
lives of your new customers a little easier and spare the net some bandwidth.

--Bruce Florman

Lawson.English@p88.f15.n300.z1.fidonet.org (Lawson English) (02/09/91)

Bruce Florman (bflm writes in a message to All

BF(> My exception handling module is probably also a good candidate 
BF(> for posting, is there any interest out there

Por favor: post it.


Lawson
 

--  
Uucp: ...{gatech,ames,rutgers}!ncar!asuvax!stjhmc!300!15.88!Lawson.English
Internet: Lawson.English@p88.f15.n300.z1.fidonet.org