C#keyword固定/不安全的用途是什么?
例如,http://www.dotnetperls.com/fixed
using System;
class Program
{
unsafe static void Main()
{
fixed (char* value = "sam")
{
char* ptr = value;
while (*ptr != '\0')
{
Console.WriteLine(*ptr);
++ptr;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
为什么我需要首先解决它?谢谢
mar*_*mnl 30
C#是一种托管语言,意味着内存是自动管理的,即不是由您管理的.如果您在fixed修改指针所指向的内存时没有使用C#,可能已将变量移动到另一个内存位置,因此您可能正在修改其他内容!
fixed 在逻辑上将变量固定在内存中,因此它不会移动.
为什么C#会在内存中移动变量?为了压缩内存,如果不再存在的对象留下其他对象无法容纳的空洞(堆内存碎片),程序将耗尽更多可用内存.
我在一个专为资源受限设备设计的.NET库中fixed广泛使用,以避免将垃圾复制到缓冲区中,并且发现此功能在其他托管语言中非常缺乏,而您无法做到这一点.在托管语言中编写游戏时,垃圾收集通常是最大的瓶颈之一,因此不具备创建它的能力非常有帮助!
在这里查看我的问题:C#将变量复制到缓冲区而不创建垃圾?原因之一.
Mar*_*ell 12
unsafe 有必要处理指针.
fixed 有两个用途:
unsafe struct字段中使用时,它声明一个"固定缓冲区" - 一个通过指针而不是常规字段访问的类型的保留空间块回答一个具体的例子 - 这里有一些代码用于执行两个byte[]任意大小之间的语义相等...
internal static unsafe int GetHashCode(byte[] value)
{
unchecked
{
if (value == null) return -1;
int len = value.Length;
if (len == 0) return 0;
int octects = len / 8, spare = len % 8;
int acc = 728271210;
fixed (byte* ptr8 = value)
{
long* ptr64 = (long*)ptr8;
for (int i = 0; i < octects; i++)
{
long val = ptr64[i];
int valHash = (((int)val) ^ ((int)(val >> 32)));
acc = (((acc << 5) + acc) ^ valHash);
}
int offset = len - spare;
while(spare-- != 0)
{
acc = (((acc << 5) + acc) ^ ptr8[offset++]);
}
}
return acc;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,例如,如果缓冲区是1000个项目,通过将其视为一组long我们现在只进行125次迭代而不必单独查看所有1000次 - 我们完全绕过任何数组边界检查(JIT可能或可能不要删除,取决于它看起来多么明显,你不可能违反它们).
Unsafe代码块很少被使用。如果您想创建和使用指针,则主要使用它们。此外,不安全块中的任何代码都不受 CLR 的控制。就 CLR 而言,它被认为是无法验证的(来自 MSDN)。
现在,当垃圾收集发生时,某些对象很可能会被重新定位。当前缀为fixed时,我们告诉框架不要重新定位地址指针所指向的对象。