Swapping two strings in memory without declaring a third variable

UPDATE: as many readers have pointed out; the title is maybe more appropriately stated “without copying the array” instead of “without declaring a third variable”.

Alright, as an introduction, this is just for fun. But I challenged myself to see if I could swap two strings, of the same length, in memory, without declaring a third. I’m not saying this is of a lot of use; but it’s fun! However, if you had massive string manipulation you might find this helpful because it’s exceptionally more performant!

As a set of prerequisites to this, you’ll need to know pointer arithmetic and also understand the exclusive-OR (XOR) operator. I’m going to go over them briefly, but not in depth. In this example we’re going to take two strings:

var a = "hello";
var b = "mike!";

and make the value of a be the value of b and the inverse without declaring a third variable. So in the end, a will be mike! and b will be hello. How are we going to do that? We are going to leverage the age old set of operations to do this:

a = a ^ b;
b = b ^ a;
a = a ^ b;

However, with strings it’s not that straight forward because the XOR operation is only allowed on numeric types. So, we’re going to have to read the strings, one character as a time, in an numeric fashion. Thankfully that’s possible in .NET because the char class, which a string is a collection of, is 16-bits (presumably to support Unicode) so we can read each character as a short. Here is the code:

class Program
{
    static void Main(string[] args)
    {
        var a = "hello";
        var b = "mike!";

        Console.WriteLine(a);
        Console.WriteLine(b);

        Console.WriteLine();

        unsafe
        {
            fixed (char* asrc = a)
            {
                fixed (char* bsrc = b)
                {
                    var aptr = (short*)asrc;
                    var bptr = (short*)bsrc;

                    for (int i = 0; i < a.Length; i++)
                    {
                        *aptr = (short)(*aptr ^ *bptr);
                        *bptr = (short)(*bptr ^ *aptr);
                        *aptr = (short)(*aptr ^ *bptr);

                        aptr++;
                        bptr++;
                    }
                }
            }
        }

        Console.WriteLine(a);
        Console.WriteLine(b);
    }
}

So, let’s break it down a little. First we turn the strings into char*, so we are now capable of iterating one character at a time, but with a pointer to the memory address. This means we can now read it in a different fashion as well. So, next we cast each char* to a short*. Now, when we get the value at the memory address, *aptr, it’s going to return a short that represents the ASCII value of that character.

Well, now that we have a numeric value, we can perform the operation on each character; iterating one at a time on each pointer until we get to the end.

Granted, I probably didn’t have to do this with pointers, but it was fun! You could have probably iterated through the strings one char at a time and just changed the value of those indexes in the array; but that’s not as fun!

Until next time, happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>