Q41247: Use Huge Pointers If Object Is Larger Than 64K Boundary
Article: Q41247
Product(s): See article
Version(s): 5.10
Operating System(s): OS/2
Keyword(s): ENDUSER | SR# G890201-11081 | mspl13_c
Last Modified: 16-MAY-1989
Question:
I'm declaring a pointer that points into an array by saying the
following:
char huge carray[70000];
char *pchar = carray;
I compile the program using large-memory model.
When I access the array using carray, everything work correctly.
However, when I use the pointer pchar, I can't seem to access the
array past the 64K boundary. What's wrong?
Response:
The problem is caused by using a far pointer in a situation where you
need a huge pointer.
There are three types of data pointers in Microsoft C: near, far, and
huge. Near pointers represent offsets within DGROUP (the default data
segment) and are stored in 2 bytes. Far and huge pointers contain both
a segment address/selector and an offset and therefore take 4 bytes.
Although far and huge pointers are identical in format, the algorithms
used to do addressing calculations involving these two types of
pointers are very different. Far pointers are assumed to point to a
data item that does not cross a segment boundary (in other words, the
size of the item must be less than 64K). As a result, the compiler
ignores the segment part of the pointer in all calculations except for
"equals" and "not equals" tests. This gives a considerable (more than
2 times) savings in execution time for these operations. In fact,
calculations involving far pointers are almost as fast as calculations
involving near pointers.
Huge pointers may point to items that are larger than 64K. The
addressing arithmetic work on both the segment and the offset, if
necessary. Huge pointer arithmetic is therefore considerably slower
than far arithmetic, but it has the advantage of working when the data
item is larger than 64K.
Your code should work correctly if you declare pchar to be a huge
pointer rather than a far (default for large-memory model) pointer. If
you didn't want to add the huge keyword to the declaration, you could
compile with the /AH option. It is recommended to use the huge keyword
rather than /AH because it allows you to control when huge arithmetic
is performed -- if you use /AH, then ALL pointers are huge.
THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.
Copyright Microsoft Corporation 1986-2002.