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