RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 591101
Accepted
i-one
i-one
Asked:2020-11-15 14:38:20 +0000 UTC2020-11-15 14:38:20 +0000 UTC 2020-11-15 14:38:20 +0000 UTC

我在用这种方式阅读什么样的记忆?

  • 772

假设有一个字节数组

byte[] bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

像这样

[StructLayout(LayoutKind.Explicit)]
struct ByteToUlongConverter
{
    [FieldOffset(0)]
    public byte[] bytes;

    [FieldOffset(0)]
    public ulong[] ulongs;

    public ByteToUlongConverter(byte[] bytes)
    {
        this.ulongs = null;
        this.bytes = bytes;
    }
}

结构体。

接下来,有了这个结构,我做

ByteToUlongConverter conv = new ByteToUlongConverter(bytes);

foreach (ulong ul in conv.ulongs)
    Console.WriteLine($"{ul:X16}");

这输出类似

0807060504030201
793C086C00000000
0000000000000000
0000000000000000
0000000000000000
0000000004710B40
00000001793BFDD8
793BED0C00000000

那些。我分配了8个字节,读了64个(你甚至不仅可以读,还可以写东西)。

这些额外的字节是谁的?这是什么记忆?那些。据我所知,我的阵列位于堆中的某个地方,而这是附近的东西。.Net 中的堆是如何组织的,所有进程都一样还是每个进程都有自己的堆?那些。另一个没有特权的进程可以尝试以这种方式读取我进程中的某些内容吗?

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Mark Shevchenko
    2020-11-15T15:19:52Z2020-11-15T15:19:52Z

    没错,就是字节数组后面的堆内存。.NET 中的堆是每个应用程序域一个,或者相对来说,一个应用程序一个。垃圾收集器完全与堆一起工作,如果由于相邻的应用程序,您还必须停止应用程序以释放内存,那就不是很好了。

    但是请注意,进程和应用程序域是不同的概念。一个进程是 Windows 内核的一种结构,在一个进程中可以有许多应用程序域,因为它们(大概)是受管理的——也就是说,它们不能只是进入彼此的内存。但是,由于这是一个 Windows 进程,因此理论上,如果它们使用非托管代码,它们肯定会破坏彼此的内存。

    因此,.NET 不允许您只运行非托管代码(请参阅托管/非托管代码互操作性概述中的安全部分)。由于硬件限制,另一个进程肯定无法进入您的内存,除非您非常明确地允许,否则另一个应用程序域也不能。

    顺便说一下,堆也不是普通的块序列——为了提高垃圾收集的性能,它分为两部分:小对象和大对象。

    现在专门介绍您的代码。您在同一地址有两个数组。在.NET中,数组的大小是存储在最开始的,分配了8个字节,也就是一个类型的数字System.Int64。原始数组的长度为 8。当您尝试像处理 的数组一样处理此数组时ulong,长度保持不变,即 8,但元素本身变大 8 倍。所以你可以读取 8×8 个字节而不是 8 个。

    但有时会因为数组经过操作系统分配的段边界而出现异常,这将是一个纯粹的硬件异常。如果您尝试向ulong数组写入内容,则行为将不可预测。堆中的每个块前面都有一个服务标头,因此从第 9 个字节开始就可以找到这样的标头,因此应用程序可能会在下一次垃圾回收时崩溃。

    • 14
  2. Pavel Mayorov
    2020-11-15T15:02:41Z2020-11-15T15:02:41Z

    该数组已分配到托管堆上。输出的第一行实际上显示了原始字节数组。

    因此,在剩余的行中 - 托管堆的随机片段。


    PS不要使用类似的转换黑客,使用更好BitConverter

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5