// ******************************************************************************** // // **Creator: Dazzle Licence: Diku Merc Smaug Terms ** // // **Difficulty: 4 Snippet: StrAlloc/Quicklink Change ** // // ******************************************************************************** // // ** Contact Information ** // // **Yahoo: ldevil.geo Msn: ldevil@hotmail.com ** // // **Aim: pocketweasle Email: sandstorm@arthmoor.com ** // // **Webpage: http://sandstorm.arthmoor.com ** // // ******************************************************************************** // // **Terms of Usage: ** // // **Follow the Diku, Merc, Smaug Licences, also, if you have a snippet helpfile ** // // **Put my name in there, if not, leave my name in the source. ** // // **Also, this code is given AS-IS, straight from my mud, so there will be some ** // // **Effort required to make this work in your mud. ** // // **Install at your own risk, if you have any comments or questions on this ** // // **Visit the website mentioned above, and enter the forum, post and bugs or ** // // **suggestions there. ** // // ******************************************************************************** // Okay, first off, this code was ripped from my mud, which is a rom/smaug hybrid mud, I have enhanced the str_alloc and quick_link functions, now, the STRALLOC and DISPOSE variables have been enhanced by samson, i am posting those changes here aswell just incase someone out there doesn't visit the smaugfuss site to get these. In anycase, is what this does is enhance your str_alloc and quick_link to destroy potential crash's in them. now, STRALLOC will alloc memory multipul times, so if you STRALLOC the same variable, it will give it, its own mark in the table, so instead, we check the hash table before we STRALLOC, if it is already in the hash-table, it will result in a quicklink. Now, quicklink will check if the string is in the table, and here is the main crasher, if you quicklink to a variable that doesn't exist, this will generaly cause a crash, so now, the code will check for the string in the hash-table first, and then if it isn't there, it will STRALLOC it and if it is in the table, it will continue with the quicklink. Now, the DISPOSE and STRFREE enhancements, here is what they do. DISPOSE will now check the pointer, to see if it is a char * or const char *, if it is one of those, it will check the hash-table, to see if it is in the hash, if it is, it will str_free it, if it isn't in the table, it will simply free it like it should. STRFREE will check for the string in the hash-table, if it doesn't exist, it will try running DISPOSE on the data, this should eliminate all the potentials for mixing up the DISPOSE/STRFREE functions. They will log any improper calls to dispose or strfree, right down to the file, function, and line of code. Making the job of the coder, allot simpler Warning: This *MAY* only work under G++, backup your code before you do this if you are not G++ compatable! #define DISPOSE(point) \ do \ { \ if( (point) ) \ { \ if( typeid((point)) == typeid(char*) || typeid((point)) == typeid(const char*) ) \ { \ if( in_hash_table((char*)(point) ) ) \ { \ nlogf( "`!Dispose called on StrAlloc pointer: %s, %s, line %d\n", __FILE__, __FUNCTION__, _LINE__ ); \ log_string( "Attempting to correct." ); \ if( str_free( (char*)(point) ) == -1 ) \ nlogf( "`!Strfreeing bad pointer: %s, %s, line %d\n",__FILE__, __FUNCTION__ , __LINE__ ); \ } \ else \ { \ free( (point) ); \ } \ } \ else \ { \ free( (point) ); \ } \ (point) = NULL; \ } \ } while(0) #define Strfree(point) \ do \ { \ if((point)) \ { \ if( !in_hash_table( (point) ) ) \ { \ nlogf( "`!Strfree called on str_dup pointer: %s, %s line %d\n",__FILE__, __FUNCTION__ , __LINE__ ); \ nlogf( "Attempting to correct." ); \ free( (point) ); \ } \ else if( str_free((point)) == -1 ) \ nlogf( "`!Strfreeing bad pointer: %s, %s, line %d\n", __FILE__ , __FUNCTION__, __LINE__ ); \ (point) = NULL; \ } \ } while(0) Okay, now the fun stuff begins. In str_alloc (in hashstr.c) before len =... it should be the first part of the handling.. put this. if( in_hash_table( str ) ) return quick_link( ( char * )str ); in quick_link, add this before ptr = it should be the first part of the actaul handling if( !in_hash_table( str ) ) return str_alloc( ( const char * )str ); at the end of hashstr.c put this.. /* * str must be the actual pointer you want to know about, it cannot be a copy * of a pointer, or a variable. */ bool in_hash_table( const char *str ) { register int len, hash, psize; register struct hashstr_data *ptr; len = strlen( str ); psize = sizeof( struct hashstr_data ); hash = len % STR_HASH_SIZE; for( ptr = string_hash[hash]; ptr; ptr = ptr->next ) if( len == ptr->length && str == ( ( char * )ptr + psize ) ) return TRUE; return FALSE; } in your mud.h with the rest of the prototypes, put this. bool in_hash_table( const char *str ); Compile clean, and have fun.. I haven't had any problems with this code, infact, it found allot of bugs for me, effectively saving my mud allot of downtime. Samson gets the credit for the strfree/dispose release, you can read more about it at www.smaugfuss.org i believe.