.NET不安全的字符串操作

时间:2012-01-10 15:35:30

标签: c# .net string unsafe

我使用下一个不安全的代码进行字符串修改:

public static unsafe void RemoveLastOne(ref string Str1)
    {
        if (Str1.Length < 1)
            return;

        int len = Str1.Length - 1;
        fixed (char* pCh1 = Str1)
        {
            int* pChi1 = (int*)pCh1;
            pCh1[len] = '\0';
            pChi1[-1] = len;
        }
    }

但是一段时间后我的C#程序崩溃了,例外:

  

FatalExecutionEngineError:   “运行时遇到致命错误。   错误的地址是0x6e9a80d9,位于线程0xcfc上。错误   代码是0xc0000005。此错误可能是CLR或中的错误   用户代码的不安全或不可验证部分。这个的常见来源   错误包括COM-interop或PInvoke的用户封送错误   可能会破坏堆栈。“

如果我将函数“RemoveLastOne”更改为“Str1 = Str1.Remove(Str1.Length - 1);”程序运行正常。

为什么会发生异常?我如何正确地在C#中实现不安全的更改字符串?

2 个答案:

答案 0 :(得分:7)

.Net中的

String值旨在不可变。在这个函数中,您将获取一个不可变的值,以几种可见的方式(内容和长度)对其进行变更,更不用说在原始数据之前写入数据了。我并不感到惊讶,这会导致后来的CLR崩溃,因为特殊情况String在几个地方值,并且在指针之前写入是危险的。

我真的不明白你为什么要在这里做不安全的操作。安全代码是直截了当的,不会导致这些类型的难以追踪错误。

答案 1 :(得分:2)

不安全的字符串操作本质上是不正确的。 .NET字符串不应该被编辑,并且很可能框架中的代码是围绕字符串永远不会改变的假设构建的。任何依赖于String.GetHashCode()的东西都会立即出现,但可能会有幕后优化或完整性检查。据推测,它会导致CLR错误。

如果您在分析后发现.NET的不可变字符串实现不符合您的需求,那么允许您修改其长度的最简单的可变替代方法是List<char>