0

While i can easily get a pointer of a char from a string:

public static unsafe void Clear(this string s)
{
        fixed (char* charPtr = s)
        {
            for (int i = 0; i < s.Length; i++)
                charPtr[i] = '\0';
        }
}

I can't seem to do the same for char: fixed (char* c = ch) does not work and gives me following error:

You cannot use the fixed statement to take the adress of an already fixed expression. Cannot implicitly convert type 'char' to 'char*'

Is there anyway in C# that I can reach the pointer of the char and delete it (= '\0')?

U. Bulle
  • 1,075
  • 9
  • 20

2 Answers2

1

The char type is already mutable. So you can simply set its value to 0.

Assume you have the following char:

char c = 'a';

Simply set it to 0 like this:

c = '\0';

I am assuming here that you have direct access to the field/variable. Note that if you receive a char as a method argument or if you get it by invoking a property, then you get a copy of the original char. If you change that to 0 then you are mutating the copy of the original char.

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
0

Since characters are passed by value, you would need to pass the character argument in by reference:

public static unsafe void Clear(ref char s)
{
    fixed (char* n = &s)
    {
        *n = '\0';
    }
}

In this case, unsafe code is unnecessary; the above can be rewritten as simply:

public static void Clear(ref char s)
{
     s = '\0';
}

Note that since the first parameter of an extension method cannot have a ref modifier, the above cannot be used as an extension method.


Separately, your Clear(string) method relies on undefined behavior. While unsafe semantics do allow to mutate a string, this can cause unexpected results. Per the language specification (emphasis added):

Modifying objects of managed type through fixed pointers can results in undefined behavior. For example, because strings are immutable, it is the programmer’s responsibility to ensure that the characters referenced by a pointer to a fixed string are not modified.

To illustrate the undefined behavior, consider the following code:

string d = "E";
string f = "E";
d.Clear();
Console.WriteLine(d);
Console.WriteLine(f);
Console.WriteLine("E");

Because of string interning, the all three strings are stored in the same memory location. As a result, the code above prints three blank lines.

If the motivation for clearing the string is to clear sensitive data from memory, a supported approach is to use SecureString. Since the GC can relocate memory as needed, there is no assurance that clearing the variable's current address will remove all references to the string from memory.

drf
  • 8,461
  • 32
  • 50
  • Thanks for the explanations and very constructive answer. I didn't know that extension method for char is sent by value. I've put `if(string.IsInterned(s) == null)` in the beginning of the string cleansing method. I already use SecureStrings but I need to show data to the user sometimes, and make sure that the data is shown in the memory as short as possible. – U. Bulle Nov 22 '15 at 10:25