A community wiki answer because it includes a lot of useful evidence, but I seem to flub the numbers somewhere:
Per OpenWatcom, the definition of _fmalloc is this. Notably:
if( amt == 0 || amt > - ( sizeof( heapblk ) + TAG_SIZE * 2 ) ) { return( NULL ); }
Allowing for integer rounding and given that size_t is 16-bit, that asserts that if the block you asked for is larger than 65536 minus sizeof( heapblk ) + TAG_SIZE * 2 then the allocation will fail.
heapblk is a struct:
struct heapblk { tag len; /* size of heap (0 = 64K) */ heapptr prev; /* segment selector/offset for previous heap */ heapptr next; /* segment selector/offset for next heap */ freeptr rover; /* roving pointer into free list */ unsigned int b4rover; /* largest block before rover */ unsigned int largest_blk; /* largest block in the heap */ unsigned int numalloc; /* number of allocated blocks in heap */ unsigned int numfree; /* number of free blocks in the heap */ freelist freehead; /* listhead of free blocks in heap */ #if defined( __WARP__ ) unsigned int used_obj_any :1; /* allocated with OBJ_ANY - block may be in high memory */ #endif };
And from line 50 of the same file, TAG_SIZE is just sizeof(tag).
On line 106 tag turns out to be a typedef for unsigned int so it's also 16 bit.
heapptr is a union defined on line 115, of a __segment and a heapblk_nptr (a.k.a. a _WCNEAR). So it's two bytes as nptr means near pointer, and a __segment means 16 bit.
freeptr is a union defined on line 120, of a freelist_nptr and an unsigned int. So also two bytes.
freelist is a struct defined on line 125 consisting of a tag, and two freeptrs. So six bytes.
So a heapblk is 22 bytes of meaningful storage:
- 8 bytes for the four
unsigned ints; - 2 bytes for the
tag (because it's another unsigned int); - 6 more for the
freelist; - 2 for the
freeptr; and - 4 in total for the
heapptrs.
That plus another 4 for the 2*TAG_SIZE is 26.
Therefore as posited elsewhere, you cannot allocate a full 64kb because some storage is reserved for heap management; however I seem to total that to 26 bytes, not 32.
sizeof(heapblk). If I can find my error I'll turn this into an answer.