Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!udel!rochester!cornell!batcomputer!rpi!quimby From: quimby@itsgw.rpi.edu (Tom Stewart) Newsgroups: comp.lang.c++ Subject: Re: How to fread a long data stream?, Turbo C++ "features" Summary: static data and the 'new' operator only work <64k Keywords: Turbo C++, new, bugs, features Message-ID: Date: 11 Dec 90 00:03:29 GMT References: <1990Dec6.202843.1@acfcluster.nyu.edu> Organization: none to speak of Lines: 68 Nntp-Posting-Host: madoka.its.rpi.edu zielinski@acfcluster.nyu.edu writes: > >Problem: Using Turbo C++, getting fread to read a large number of >data points (160,000 short integers). The following structure >worked in (Microsoft) C, but fails in Turbo C++. It will only >read 28,928 two-byte data; this corresponds to the remainder of >160000/65536. > > long NumPts=160000L; > long NumRead; > static short huge x[160000L]; > printf("Array size is %ld\n",(long)sizeof(x)); /* OK up to here */ > Numread=fread(x,sizeof(short),NumPts,file1); /* only reads 28,928 */ > "..even though the huge model permits static data to total more than 64k, it still must be less than 64K in each module" p. 199, Turbo C++ Programmer's Guide If you enable stack checking (default is not), the above program segment will terminate with a stack overflow. The solution to this problem would seem to be: short huge *x; x = new x[160000l]; // this does not work in Turbo C++ The problem with this is that 'new' calculates the size as a 16 bit value in the AX register, pushes this on the stack, and calls 'operatornew' to allocate the memory, which in turn calls 'malloc'. There is no way to allocate more than 64k at a time with 'new'. (A call to Borland's tech support verified this as well.) The fix is to use farmalloc instead: x = (char huge *) farmalloc(16000l); // this works ok Be sure to cast to long before multiplying the farmalloc parameter. The nasty bit of all this is that the allocations return valid pointers, not NULL, and the pointers point to areas much smaller than requested, AND that the array indexes, if used, don't wrap around the allocated block, if they wrap at all. When using new, then, the programmer either has to verify that the size is <64k before the allocation, or check to see if the size of the allocated block is large enough after allocation. A way to check the alloc in the huge model is: unsigned huge *dummy; unsigned size; /* please note that not only is this a kludge, it is a non-portable, undocumented kludge. It is, however, usefull for debugging (MS-DOS 3.30) */ dummy = (unsigned huge*) x; dummy = dummy - 2; // MS-DOS allocated memory has a 4 byte header size = *dummy; // size is the number of paragraphs, including the // header // (1 paragraph == 16 bytes) Is there any clean way around this mess? Quimby (replies to: quimby@mts.rpi.edu, quimby@rpitsmts.bitnet)