grimlok@hubcap.clemson.edu (Mike Percy) (05/29/90)
e89hse@rigel.efd.lth.se writes: >>>char huge *files; >>>int i; >>> >>>files=(char huge *)farmalloc(2000L*82L); >>> >>>for (i=0; i<2000; i++) >>> strcpy(&files[i],"Some kind of character string"); >>> >>>for (i=0; i<2000; i++) >>> puts(&files[i]); >>> > Either you had a bad day programing this or you're really lost: Looks like you're the one who was really lost. >1) An int has the range -32768 <= n <= 32767, and 82*2000 is obviously not > <= 32767 if you're using a 16-bit processor. (Ok we can argue a whole > lot about that but I guess it's true for this the ase here.) 1) farmalloc takes an unsigned long argument. 2000L*82L = 164000L, with a conversion to unsigned (which in this case does, effectively, nothing). >2) The idea with small memory model is that you use less than 64k of data, > otherwise you're probably better off using big model rather than try > to fix it, unless you're desperate for performance. 2) The idea behind the small memory model is that you use less than 64k of static (i.e. pre-allocated) data. You can use much more than that in dynamically allocated data space, although each hunk must be less than 64K, unless you use far*alloc, which is what he did. >3) If you really want to minimise the memory usage why do you have a fixed > array? (Many lines are probably less than 81 characters long.) An > array with ptr to ptr or something would probably be more compact. Pointer to pointers would do the trick, from what I read into the article, he wants something like this: char far * far *files; /* want far ptr to far ptrs */ /* avoid using huge ptrs if at all possible */ files = (char far * far *) farcalloc(2000,sizeof(char far *)); for(i = 0; i < 2000; i++) files[i] = (char far *) farmalloc(82); /* each of them points to 82 */ /* chars */ > > Mixing memory models isn't easy. If you know what you're doing you'll have a >hard time doing it, otherwise you'll just waste a lot of time. Someone else said that you'd have to write your own strcpy, etc. routines. This is not necessarily the case, but is probably best. My experience has proven that if you can do it all in one memory model, do it. If not, see if you can change things so that you can do it. If that fails, make sure you know what the hell you're doing, otherwise you'll end up rebooting a lot.
e89hse@rigel.efd.lth.se (05/29/90)
In article <9136@hubcap.clemson.edu>, grimlok@hubcap.clemson.edu (Mike Percy) writes: >e89hse@rigel.efd.lth.se writes: >>>>char huge *files; >>>>int i; >>>> >>>>files=(char huge *)farmalloc(2000L*82L); >>>> >>>>for (i=0; i<2000; i++) >>>> strcpy(&files[i],"Some kind of character string"); >>>> >>>>for (i=0; i<2000; i++) >>>> puts(&files[i]); >>>> > >> Either you had a bad day programing this or you're really lost: >Looks like you're the one who was really lost. Probably I should have used a more humble langauge. >>1) An int has the range -32768 <= n <= 32767, and 82*2000 is obviously not >> <= 32767 if you're using a 16-bit processor. (Ok we can argue a whole >> lot about that but I guess it's true for this the ase here.) >1) farmalloc takes an unsigned long argument. 2000L*82L = 164000L, with >a conversion to unsigned (which in this case does, effectively, >nothing). Agreed, but: 1) for(i=0; i < 2000; i++) strcpy(&files[i],"gfdskjhfdsg"); (QUE????) (and then somone suggested: for(i=0; i < 2000l*82l; i+=82) ... willcause mayor trouble if i is an int..., but that is a detail >>2) The idea with small memory model is that you use less than 64k of data, >> otherwise you're probably better off using big model rather than try >> to fix it, unless you're desperate for performance. >2) The idea behind the small memory model is that you use less than 64k >of static (i.e. pre-allocated) data. You can use much more than that in >dynamically allocated data space, although each hunk must be less than >64K, unless you use far*alloc, which is what he did. I'm not sure if we are using the same defintion of small memory model, but in Turbo-C at least, the definition of the memory models are basically: tiny : code+data < 64k small code < 64k && datae < 64k medium code unlimited && data < 64k compact code < 64k && pre-init (that is static) < 64k and malloc unlimited large code unlimited && pre-init < 64k and malloc unlimited huge code unlimited && pre-init unlimited && malloc unlimited (medium and compact is maybe the other way around) The advatage with small is that only a 16-bit is required to store ptrs thus the standard functions only take 16-bit arguments and therefore cannot deal with far ptrs. >>3) If you really want to minimise the memory usage why do you have a fixed >> array? (Many lines are probably less than 81 characters long.) An >> array with ptr to ptr or something would probably be more compact. >Pointer to pointers would do the trick, from what I read into the >article, he wants something like this: > >char far * far *files; /* want far ptr to far ptrs */ > /* avoid using huge ptrs if at all possible */ >files = (char far * far *) farcalloc(2000,sizeof(char far *)); >for(i = 0; i < 2000; i++) > files[i] = (char far *) farmalloc(82); /* each of them points to 82 */ > /* chars */ The char far * far * looks weird to me, but that migt be right. Anyhow what I ment was that he probably wants to store a 2000 strings of varied size in an array. And most strings won't be 81 chars, but less. Those it would be more compact with an array of ptrs. Maybe something like this: area=malloc(BUFSIZE); files=malloc(2000*sizeof(char *)); for(i=off=0; i < 2000; ++i) { strcpy(area+off,whatever (which is probably not a const string)); files[i]=area+off; off+=strlen(area+off)+1; } for(i=0; i < 2000; +=i) puts(files[i]); Well and then some more checks (to see that malloc is ok and off doesn't exceed BUFSIZE). Henrik Sandell
grimlok@hubcap.clemson.edu (Mike Percy) (05/30/90)
darcy@druid.uucp (D'Arcy J.M. Cain) writes: [stuff about mixed mode strcpy] >#define mixstrcpy(d, s) { int k = 0; do d[k] = s[k]; while (s[k++]);} >At that point it is probably just as easy to put it inline any way. I >tested the above on Unix but it should work on brain dead OS's as well. With one, possibly trivial, problem. As I have pointed out here before, unless d and s are both huge pointers, the [] operators will fail when used to address items whose byte offset from &array[0] is greater than 64K (we are talking about Intel here, after all). This might need to be #define mixstrcpy(d, s) \ { \ while(*(char huge *)d++ = *(char huge *)s++); \ } We have to use huge; far isn't sufficient, as it wraps around in its segment. But again, unles you know you have really mongo large structures, avoid using huge and incurring its overhead.