.NET不安全的字符串操作

本文关键字:操作 字符串 不安全 NET | 更新日期: 2023-09-27 18:19:51

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

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#程序崩溃,出现异常:

致命执行引擎错误:"运行时遇到致命错误。错误的地址位于线程0xcfc上的0x6e9a80d9。错误代码为0xc0000005。此错误可能是CLR或用户代码的不安全或不可验证的部分。这方面的共同来源错误包括COM互操作或PInvoke的用户封送处理错误可能会损坏堆栈。"

如果我将函数"RemoveLastOne"更改为"Str1=Str1.Remove(Str1.Length-1);",程序运行良好。

为什么会出现异常?以及如何在C#中正确实现不安全的更改字符串?

.NET不安全的字符串操作

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

我真的看不出你为什么要在这里进行不安全的操作。安全的代码是直接的,不会导致这些类型的难以追踪的错误。

不安全的字符串操作本质上是不正确的。NET字符串不应该被编辑,而且框架中很可能有一些代码是基于字符串永远不会改变的假设构建的。任何依赖String.GetHashCode()的东西都会立刻浮现在脑海中,但可能会有幕后优化或健全性检查。大概是类似的原因导致了CLR错误。

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