page@swan.ulowell.edu (Bob Page) (03/24/88)
Arrggh.. I did some poking around & found out that yes, it does work in 8-byte chunks. Seems logical, since that's how AllocMem() works. I never checked the memory list after my call to FreeMem() ... turns out that it was not being changed at all! Kinda strange, but who knows what evil lurks in the heart of DOS. It also means this code that looks so pretty and is commented so well will never work. I still _want_ it to work. If I run the program once or twice, and never touch it after that, I can work for days with no problems. Ah well. ..Bob -- Bob Page, U of Lowell CS Dept. page@swan.ulowell.edu ulowell!page "Nicaragua" is Spanish for "Vietnam."
cmcmanis%pepper@Sun.COM (Chuck McManis) (03/24/88)
This is a great question, mostly because I think I know the answer :-), but partly because the answer isn't documented *anywhere*. In article <5650@swan.ulowell.edu> page@swan.ulowell.edu (Bob Page) writes: >The RKM states that AllocMem() will round your byte request up to the >next 8-byte boundary (and says don't count on this). > >The autodocs say FreeMem() will free space that you've allocated. >Does it also round up to the nearest 8 bytes? Definitely YES. FreeMem() and AllocMem() calculate how many bytes you really have by the same formula so as long as you don't lie to it about those sizes you are safe. (If you allocate a 16 byte chunk and try to free it in 16 one byte chunks it is guru city.) >The FreeMem() doc says/implies that it must be my memory, or at least >something that was allocated in some system-nice way. This is correct so far ... >That is, I'm copying a DOS list to my own list, pointing DOS at it, >then deallocating the old list. I know you're all shaking, saying >"don't you DARE deallocate one of DOS's lists!" but I think I'm doing >it in a very safe way, and don't think the stuff in this list is >contained anywhere else, like in DOS's stack or anything. /**** Save this you DOS hackers out there *******/ Ah but here is the kicker, DOS doesn't use AllocMem() to get it's memory! Turns out, (and I found this out when trying to debug my Assign.c program and which Andy Finkel later verified by presumably looking at the source...) DOS allocates memory with two constraints, 1) The memory allocated is an even number of long words (multiple of 4 bytes), *AND* puts the length in bytes into the long word *before* the address it returns. So lets say you allocate 6 bytes for an Assign, you could do it like this ULONG * DOSmalloc(size) int size; { ULONG *A; A = (ULONG *)AllocMem((size+7)/4); *A = (size+7)/4 return(A+1); } Now this is included in Arp (DOSAlloc() and DOSFree()). The nice part of this scheme is that DOSFree can be the macro #define DOSFree(p) FreeMem((ULONG *)(p)-1,*((ULONG *)(p)-1)) Which uses the length previously stored in memory. Make you DOS lists with memory allocated in this fashion and your Amiga will stop crashing when you play with DOS lists. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.