gpt4 book ai didi

c# - 不安全 C# 的变态,内存堆栈分配

转载 作者:太空狗 更新时间:2023-10-29 22:52:48 24 4
gpt4 key购买 nike

我在这里尝试使用 C# 的不安全特性:http://ideone.com/L9uwZ5

我知道,这种方式在 C# 中是最糟糕的,我想承认,主题中有一些信息。看看“变态”这个词。

我想在 C# 中像纯 C 方式(甚至不是 C++)一样实现快速排序。这可能很疯狂,但只是想深入了解不安全 C# 的可能性。

我一直在尝试使用 stackalloc 运算符。我知道,这是从堆栈分配的,而不是从堆分配的,这就是我执行程序失败的原因。

但是当我在这个程序中没有看到任何异常/错误时,我很困惑。

  • 为什么我没有收到任何明确的异常/错误?

另外,正如您看到的代码注释部分:

struct Header
{
internal int* data;
};

Header* object_header = stackalloc Header[sizeof(Header)];
object_header->data = stackalloc int[length];

我不能用最后一行编译它。 C# 编译器告知,在此表达式中不能使用 stackalloc。为什么?数据是int*类型,为什么这里会报错?

我只想使用堆栈框架而不使用堆。我知道,还有另一种方法,但它是从堆中分配的。

int*[] data = new int*[length * sizeof(int)];
IntPtr result = Marshal.AllocHGlobal(Marshal.SizeOf(length * sizeof(int)));
Marshal.WriteInt32(result, 0);
for(int i = 0; i < length * sizeof(int); i++) d[i] = (int*)result;

例如,但它不是堆栈分配。

如何使用 C# 语言中的堆栈分配和纯 C 风格语法显式解决我的变态任务。

C# 不是为了这样的目标而创建的,这样的特性是愚蠢的——我知道,但主要问题不是重要性,而是关于这样的特性。

最佳答案

Marc 展示了解决方法,我将尝试解释为什么需要这样做。实际上,您正在编写非托管代码,但该方法在很大程度上仍然是托管方法。它从 IL 编译成机器代码,其堆栈帧和 cpu 寄存器将由垃圾收集器搜索对象引用。

抖动在编译方法时执行两个重要任务。一个是显而易见且高度可见的,将 IL 转换为机器代码。但是还有另一个非常重要的任务,它是完全不可见的,它为方法生成元数据。一张表,显示堆栈帧的哪些部分包含对象引用以及哪些部分存储指针和值类型值。并且在代码中的哪些点 cpu 寄存器将存储对象引用。此外,对象引用在方法代码中的什么位置超出范围。 GC.KeepAlive() 的原因,这是一种完全不生成代码的非常独特的方法。

垃圾收集器需要那个表来可靠地找到对象引用。然而,该表只有一个间接级别。它可以描述为object_header分配的堆栈空间,并将指针和指向的堆栈区域标记为“不扫描对象引用”。当你直接分配object_header->data时,它不能描述堆栈空间的 block 。它没有额外的间接方式将堆栈分割为更小的部分并描述 Header。使用虚拟局部变量解决了这个问题。

关于c# - 不安全 C# 的变态,内存堆栈分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13564899/

24 4 0
文章推荐: java - 如何调试JSTL?
文章推荐: c# - 带可更换元素的 key 系列
文章推荐: c++ - 抓老鼠?
文章推荐: c# - 列表字典
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com