Path: utzoo!attcan!uunet!know!samsung!emory!hubcap!grimlok From: grimlok@hubcap.clemson.edu (Mike Percy) Newsgroups: comp.lang.c++ Subject: Re: Borland's C++ memory allocation problems Message-ID: <10370@hubcap.clemson.edu> Date: 7 Sep 90 17:13:43 GMT References: <59280@bbn.BBN.COM> <10344@hubcap.clemson.edu> <57213@microsoft.UUCP> Organization: Clemson University, Clemson, SC Lines: 73 jimad@microsoft.UUCP (Jim ADCOCK) writes: >In article <10344@hubcap.clemson.edu> grimlok@hubcap.clemson.edu (Mike Percy) writes: >[re a structure containing a hugh array] >>Are you also new to the Intel chip structure -- this is the main root of >>these problems. An understanding of the languages invloved helps. An >>understanding of the machine lets you vent your anger at Intel when you >>see all the stupidities that have to be built into Intel compilers. >I disagree. Lots of compilers restrict structure size to 64K -- even >on machines with 32-bit flat pointers. Many machines have instruction >sets that make short offsets into structures desirable. So, if you write >code expecting huge structures to work, Intel is the least of your >problems. Hadn't thought of that; virtually all of the C/C++ work I do is on a PC, and I KNOW the kind of things that go on here, I made the mistake of assuming that more sensible architectures didn't have these problems. My beef here is that when people can't/don't/won't understand the limitations the machine can put on the compiler, or the limitations of the compilers (we can't have realistically have limitless, perfect compilers) the first words out of their mouth tend to be "compiler bug." >The "right" thing to do is to make the array a separate allocation, >Intel chip, or no Intel chip. A separate allocation might help sometimes, but TC/TC++ still uses size_t of unsigned int (16-bits), so no way can you get over 64K from malloc(). You could use farmalloc(unsigned long) (32-bit), but the standard conversions can cause huge headaches. farmalloc(1000 * 100); Let's see, 1000 is a decimal constant < 32767, as is 100; both are typed to be signed int. A signed int * signed int is a signed int. The result is converted to an unsigned long for the function call (we always have a prototype in scope, right?). So 1000 * 100 = 100000, but oops, we have to truncate it to fit 16 bits, we have 34465 as the intermediate result. But this is signed, so the value is really -34464. The conversion to long sign extends, but we treat the resultant long as unsigned. It has a value 0xFFFF86A0. That much space surely won't be available on the heap! The correct way do do this is farmalloc(1000ul * 100ul); Now everything is hunky-dory and assuming there is 100K or so of space on the heap, this will succeed. The above could have been worse though: What if we try farmalloc(1000 * 70); After the multiplication and truncation, we end up asking farmalloc for 4464 bytes, which it can surely get for us, but since the result is not NULL, the careless program[mer] will mistakenly assume the it got the 70000 bytes it thought it requested. Who knows what will happen when a write to the area after the "safe" 4464 byte zone occurs? When stuff like the above happens, the most frequent complaint is "Hey, I've found a compiler bug!" I have to look up and think "Forgive them, they know not what they do..." Maybe the above should go into the TurboC FAQ list, if it hasn't recently been added. >[Personally, I find 386/486 machines have fine support for OOPL. 286s I >find frustrating. Consider that for a little over $1K I can buy a 386sx >machine with 40Meg disk, 1Meg ram, 640x480 gray-scale display, etc. Or >I can maybe buy a non-Intel machine with a tiny BW display and only a >single floppy drive.... [standard disclaimer] ] I know EXACTLY what you mean... "I don't know about your brain, but mine is really...bossy." Mike Percy grimlok@hubcap.clemson.edu ISD, Clemson University mspercy@clemson.BITNET (803)656-3780 mspercy@clemson.clemson.edu