简体   繁体   English

.NET不安全的字符串操作

[英].NET Unsafe string manipulation

I use next unsafe code for string modifying: 我使用下一个不安全的代码进行字符串修改:

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;
        }
    }

But some time later my C# programm crash with exception: 但是一段时间后我的C#programm崩溃了,例外:

FatalExecutionEngineError: "The runtime has encountered a fatal error. The address of the error was at 0x6e9a80d9, on thread 0xcfc. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack." FatalExecutionEngineError:“运行时遇到致命错误。错误地址为0x6e9a80d9,在线程0xcfc上。错误代码为0xc0000005。此错误可能是CLR中的错误或用户的不安全或不可验证部分此错误的常见来源包括COM-interop或PInvoke的用户封送错误,这可能会破坏堆栈。“

If I change function "RemoveLastOne" to "Str1 = Str1.Remove(Str1.Length - 1);" 如果我将函数“RemoveLastOne”更改为“Str1 = Str1.Remove(Str1.Length - 1);” program works fine. 程序工作正常。

Why exception happens? 为什么发生异常? And how I can implement unsafe change string in C# correctly? 我如何正确地在C#中实现不安全的更改字符串?

String values in .Net are intended to be immutable. .Net中的String值旨在是不可变的。 In this function you are taking an immutable value, mutating it in several visible ways (content and length) not to mention writing data before the original. 在这个函数中,您将获取一个不可变的值,以几种可见的方式(内容和长度)对其进行变更,更不用说在原始数据之前写入数据了。 I'm not surprised at all that this would result in a later CLR crash as it special cases String values in several places and writing before the pointer is simply dangerous. 我并不感到惊讶,这会导致后来的CLR崩溃,因为它的特殊情况在几个地方的String值并在指针之前写入是危险的。

I can't really see a reason why you'd want to do the unsafe manipulation here. 我真的不明白为什么你想在这里做不安全的操作。 The safe code is straight forward and won't cause these types of hard to track down bugs. 安全代码是直截了当的,不会导致这些类型的难以追踪错误。

Unsafe string manipulation is inherently incorrect. 不安全的字符串操作本质上是不正确的。 .NET strings aren't supposed to be edited, and it's most likely that there is code in the framework that is built around the assumption that a string will never change. .NET字符串不应该被编辑,并且很可能框架中的代码是围绕字符串永远不会改变的假设构建的。 Anything that relies on String.GetHashCode() comes immediately to mind, but there might be behind-the-scenes optimizations or sanity checks. 任何依赖于String.GetHashCode()的东西都会立即出现,但可能会有幕后优化或完整性检查。 Presumably it's something like that which is causing the CLR error. 据推测它就是导致CLR错误的东西。

If you're finding, after profiling, that .NET's immutable string implementation does not fit your needs, the easiest mutable alternative that would let you modify its length is a List<char> . 如果您在分析后发现.NET的不可变字符串实现不符合您的需求,那么允许您修改其长度的最简单的可变替代方法是List<char>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM