huge problem

Bob Babcock PEPRBV%CFAAMP.BITNET at MITVMA.MIT.EDU
Wed Mar 23 10:55:03 AEST 1988


I seem to have found  a problem  with  huge pointers  in Turbo  C
1.5.  The following  program can be compiled  with either Turbo C
or MSC 5.0 to demonstrate  the problem.   Note that both  Borland
and  especially  Microsoft  are a little  vague  about  the exact
properties  of huge pointers,  and since huge is an extension  of
ANSI standard, there's no place beyond their manuals to look.

By the  way,  do people  at Borland  (and  Microsoft)  see  these
lists?  I'll probably file an official bug report eventually, but
so far I haven't even bothered to mail in my registration cards.

----------
#include <stdio.h>

#ifdef __TURBOC__
#include <alloc.h>
#define ALLOCATE(x,y) farcalloc(x,y)
#else
#include <malloc.h>
#define ALLOCATE(x,y) halloc(x,y)
#endif

/* Compile this with the large model flag under Turbo C 1.5 to demonstrate
   an apparent problem with huge pointers to structures.  MSC 5.0 seems to
   get it right.
 */

struct record
   {
   unsigned char string[28];
   unsigned long stuff;
   };

void main(void)
   {
   struct record huge *xx;
   struct record *aa,*bb,*cc;

   xx=(struct record huge *)ALLOCATE(3001L,
                                    (unsigned long)sizeof(struct record));

#ifdef __TURBOC__
   printf("Output when compiled with Turbo C 1.5, large model\n");
#else
   printf("Output when compiled with MSC 5.0, large model\n");
#endif

   if(xx == 0)
      printf("Warning: memory allocation failed\n");

   printf("size of structure record is %d\n", sizeof(struct record));

/* Turbo C claims that huge pointers are always normalized, yet the first
   printf below prints the same segment for all 3 pointers, which is just plain
   wrong for xx[3000].string since it is more than 64K away from xx[0].string.
   More subtle is the problem with xx[2047].string which gets an offset of
   FFEC: the string crosses a segment boundary, so any use is likely to
   suffer from segment wrap around.  The second printf shows a work-around
   which gives the right answers, and may be more efficient if multiple
   references are made to the same structure.

   Microsoft C 5.0 seems to get this right.  The pointers are not normalized,
   but the starting address returned by halloc is adjusted so that the end of
   an element is exactly a segment boundary.  This is apparently why halloc
   requires that the element size be a power of 2 for arrays larger than
   128K.
 */

   printf("xx[0] - %Fp, xx[2047] - %Fp,  xx[3000] - %Fp\n",
      xx[0].string, xx[2047].string, xx[3000].string);

   aa=(struct record *)xx;
   bb=(struct record *)(xx+2047);
   cc=(struct record *)(xx+3000);

   printf("aa -    %Fp, bb -       %Fp,  cc -       %Fp\n",
      aa->string, bb->string, cc->string);


   return;
   }

Output when compiled with Turbo C 1.5, large model
size of structure record is 32
xx[0] - 5767:000C, xx[2047] - 5767:FFEC,  xx[3000] - 5767:770C
aa -    5767:000C, bb -       6765:000C,  cc -       6ED7:000C

Output when compiled with MSC 5.0, large model
size of structure record is 32
xx[0] - 6640:0000, xx[2047] - 6640:FFE0,  xx[3000] - 7640:7700
aa -    6640:0000, bb -       6640:FFE0,  cc -       7640:7700

[Your segment registers will be different, of course]



More information about the Comp.lang.c mailing list