On Thu, 23 Apr 1998, James Turner wrote: > #define ITOA_NBUF 100 > > char * > itoa(int i) > { > static char tbuf[ITOA_NBUF][MIL]; > static int n = -1; > > n = (n + 1) % ITOA_NBUF; > > snprintf(tbuf[n], MIL, "%d", i); > tbuf[n][MIL-1] = 0; > > return tbuf[n]; > } Rather than wasting memory on mostly unused static buffers and implementing such a multiple-buffer solution in each function returning a pointer to static storage, consider implementing a general solution. The idea was first introduced by Oliver Jowett in his IMC code: a pool of static storage that functions with need for static storage request from. The code looks like this: const char* itoa (int i) { char *buf = imc_getsbuf(MIL); sprintf(buf, "%d", i); imc_shrinksbuf(buf); return buf; } imc_getsbuf will return MIL bytes of space from a ring buffer: the allocation simply remembers current position in that buffer then advances that pointer the required number of bytes so that the next allocation will not get the same memory. After you print something to the buffer, you can call imc_shrinkbuf which puts that first-free-byte pointer in the ring buffer exactly at the end of the string you actually filled out the buffer with. Thus you can request a 1k buffer, but if you use only 4 bytes of it, the rest are reclaimed. The buffers are assumed to have very temporary storage, so no effort is made to preserve old buffers: when the ring buffer is filled up, we just start over. This system reduces memory usage depending on number of functions with static buffers you have: If you 40 places reserve 4k for a static buffer, you'll save 24k if you just use a 16k ring buffer. In addition, you can call a function which returns static memory several times without copying the results away, since the buffer is large enough to hold several of their results. It works even better in C++, the code looks roughly like: const char* itoa (int i) { StaticBuffer buf; // Defaults to some large value sprintf (buf, "%d", i); return buf; } The destructor for StaticBuffer takes care of automaticaly shrinking the buffer, and a conversion operator allows use of sprintf on the buffer. There are risks connected with doing this: in theory the buffer may overflow and data you thought was OK overwritten. As long as you use the data returned fairly close to where you will be OK. I use this StaticBuffer 85 places in AR's 170k lines of code and have never had any problems. Oh, another note, regarding some argument-splitting code someone - James Turner I think - posted. It's one thing to use global variables for things like a list of players or rooms in the game - but using a set of global variables for the return value of a function is a IMHO bad idea. Especially a function used for splitting arguments up - that is a thing very common to MUD code. One day someone will make a function that has split up the args and is going through them somehow recurse or it will call the split function from another function that also is accessing the split arg and you will have disaster. PS: Regarding discussion for ASCII vs binary pfiles: I have never heard any developers of any MERC 2 derived MUDs (the version which introduced ASCII pfiles) nor its many derivatives consider binary pfiles. I have never heard anyone complaint how long players took to save or load. Maybe in 1992 people complained how MERC took up 20% of their 386'er running Coherent but by now, whatever extra time saving ASCII files takes is worth less than the programmer time saved because of the extendibility they present. PPS: If I used binary pfiles on AR, I'd estimate the size of the player file to be about 82 megabyte: 6200 pfiles a 14000 bytes - and that'd be only if I put artificial limits on may things stored in lists like aliases, spell customizations, environment variables etc. ============================================================================= Erwin Andreasen Herlev, Denmark <erwin@pip.dknet.dk> UNIX System Programmer <URL:http://www.abandoned.org/drylock/> <*> (not speaking for) DDE ============================================================================= +------------------------------------------------------------+ | Ensure that you have read the CircleMUD Mailing List FAQ: | | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html | +------------------------------------------------------------+
This archive was generated by hypermail 2b30 : 12/15/00 PST