No more memory allocation!

I got around to testing the collision detection code today. I had to wring out quite a few bugs, but it’s working now. More importantly, though, I managed to solve two of my memory allocation issues. Hurrah!

I rebuilt the multithreading class.  I now have a set of Threads, each of which is running in an infinite loop (that can be broken when a flag is flipped on, of course).  I ran into a bit of a scare when the class slowed my program to a halt, but fortunately that was because of a bug– I had the code create a new instance of the Thread when it wasn’t in ThreadState.IsRunning– and apparently it doesn’t go into the IsRunning state as soon as you Start() it.

Regarding strings, it turns out that StringBuilder isn’t good enough to completely avoid memory allocations.  According to this guy (and confirmed on CLR Profiler), StringBuilder’s ToString() method will return an internal copy of its string (as opposed to a brand new, garbage-inducing copy) only once– the very first time the method is called– and even then, only if the string it’s returning is at least half of the StringBuilder’s capacity.  The author gives a solution to retrieve the internal copy… which apparently doesn’t work on XNA 4.0 anymore.  Fortunately, he did come up with another way– tap the internal string directly using unsafe code/pointers.  I personally think it’s beautiful– not only is the code simple to understand, it allows you to edit the string directly, thus bypassing the problem of the string’s immutability entirely!  Oh, the possibilities… mwahahaha….

The important piece of code here is the author’s CopyIntoString() unsafe method:

public static unsafe void CopyIntoString( string dest_string, char[] char_buffer, int length )
{
System.Diagnostics.Debug.Assert( dest_string.Length >= length );

unsafe
{
fixed ( char* dest_fixed = dest_string )
{
// Copy in the string data
for ( int i = 0; i < length; i++ )
{
dest_fixed[i] = char_buffer[i];
}

// NULL terminate the dest string
if ( length < dest_string.Length )
{
dest_fixed[length] = (char)0;
}
}
}
}

It’s as simple as declaring a char pointer onto the desired string, then doing a char-by-char edit by index!

Adapting this method, I created a class that contains a string, keeps track of its length (the code above adds a null-terminator to the string instead, but DrawString() throws an exception at this, so I had to replace the rest of the string with whitespace characters instead), and provides methods to add to the string, delete its contents (with the aforementioned whitespace characters), and convert a number variable to a string (since using ToString() would’ve caused memory allocations).

Converting a digit to a char is easy enough. I divide the number by 10 ^ desired digit (so if I want the ones place, I divide by 10 ^ 0 = 1, if I want the tens place, I divide by 10 ^ 1 = 10, if I want the hundreds place, I divide by 10 ^ 2 = 100, if I want the tenths place, I divide by 10 ^ -1 = 0.1), which pushes the desired digit into the ones place, then mod by 10 to extract the value of the digit. The formula works really well and even allows you to pull decimal numbers up to three places– the fourth place onward, the math gives slightly wrong answers, probably because of the way decimal variables only approximate the actual value.

Now to code in the actual game engine commands to access this class….

This entry was posted in News. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s