【问题标题】:Force a memory level cast强制进行内存级别强制转换
【发布时间】:2014-02-08 23:10:58
【问题描述】:

来自 C 的 Iirc,您可以按照以下方式声明:

char* str = "1234";
int nonStr = *((int*)str);

(我故意将字符串设置为 4 个字符,因此在一般情况下,它将具有与整数相同的字节数。)这将取消引用存储 str 的内存,并在它是整数时为您提供值(522207554 如果我转换正确)。

有没有办法在 C# 中做同样的事情?我知道这是一个低级内存操作,通常对 C# 程序员隐藏起来,我只是为了教学练习。

【问题讨论】:

  • 一个“教学”练习!当然,我们希望鼓励良好的习惯,而不是像这样滥用指针——尤其是在 C# 中。如果您想教授指针滥用,至少要在适当的上下文中进行 - 在低级/OS 环境中使用 C/C++。不是 C#。
  • .NET String to byte Array C# 的可能重复项
  • @Skizz 滥用它们的全部意义在于“指出”它们可能被滥用,即使是偶然的。我想解释一下幕后记忆中发生了什么,这样学生们就会明白为什么他们会得到InvalidCastException!我不打算教他们以这种方式编写“真正的”程序。
  • .NET 中有 IntPtr 对象,您可以在 unsafe 块中进行指针操作。您要从哪个指针开始操作?除非它是 IntPtr、封送处理的东西或在不安全块内创建的指针,否则就低级内存操作而言,我认为您无能为力。
  • @just.another.programmer: str 指向一个静态分配的chars 数组,严格的别名规则说(大约)你不能访问一个对象通过指向不同类型的指针进行类型(除了少数例外,这不属于)。这允许某些有时需要的优化。您问题中的代码可以使用memcpy(&nonStr, str, sizeof(nonStr)) 删除其未定义的行为。 (这会调用允许的例外之一——非char 的东西可以用作char,但反之则不行。)更多信息可在其他地方获得。

标签: c# memory casting low-level


【解决方案1】:

您可以使用不安全的上下文和fixedstatement:

static unsafe void Main(string[] args)
{
    string str = "1234";
    fixed(char* strPtr = str)
    {
        int* nonStr = (int*)strPtr;
        Console.WriteLine(*nonStr);
    }
}

打印

3276849

【讨论】:

  • C# 中的 char 是一个两字节结构(UTF-16 编码),因此您希望字符串中有 2 个字符。您可以在这里看到:十六进制的 3276849 是 0x00320031(“34”没有被复制)。
【解决方案2】:

您正在寻找 C# 的 unsafe 功能。

这里是one reference。对“C# 不安全指针取消引用”的一般搜索会出现很多结果。

【讨论】:

    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 2012-02-10
      • 2021-05-28
      • 1970-01-01
      • 2010-12-08
      • 2019-03-25
      • 2011-03-31
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多