清除内存中的字符

时间:2015-11-21 22:38:47

标签: c# pointers memory-management unsafe

虽然我可以轻松地从字符串中获取字符的指针:

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

我似乎无法对char执行相同的操作:fixed (char* c = ch)不起作用并且给出了以下错误:

  

你不能使用fixed语句来获取已经的地址   固定的表达。无法将类型'char'隐式转换为'char *'

无论如何在C#中我可以到达char的指针并删除它(='\ 0')?

2 个答案:

答案 0 :(得分:1)

char类型已经是可变的。所以你可以简单地将它的值设置为0。

假设您有以下char

char c = 'a';

只需将其设置为0,就像这样:

c = '\0';

我假设您可以直接访问字段/变量。请注意,如果您收到char作为方法参数,或者通过调用属性获得它,那么您将获得原始char的副本。如果将其更改为0,那么您正在改变原始char的副本。

答案 1 :(得分:0)

由于字符是按值传递的,因此您需要通过引用传递字符参数:

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

在这种情况下,不需要安全的代码;以上内容可以简单地改写:

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

请注意,由于扩展方法的第一个参数不能包含ref修饰符,因此上述内容不能用作扩展方法。

另外,您的Clear(string)方法依赖于未定义的行为。虽然不安全的语义允许改变字符串,但这可能会导致意外的结果。根据语言规范(强调添加):

  

通过固定指针修改托管类型的对象可能导致未定义的行为。例如,因为字符串是不可变的,所以程序员有责任确保不修改指向固定字符串的指针所引用的字符。

要说明未定义的行为,请考虑以下代码:

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

由于字符串实习,所有三个字符串都存储在同一个内存位置。结果,上面的代码打印出三个空行。

如果清除字符串的动机是清除内存中的敏感数据,则支持的方法是使用SecureString。由于GC可以根据需要重新定位内存,因此无法保证清除变量的当前地址将从内存中删除对字符串的所有引用。