gpt4 book ai didi

C#:指向空数组的不安全指针为空?

转载 作者:太空狗 更新时间:2023-10-30 00:07:48 26 4
gpt4 key购买 nike

unsafe block 中,我试图获取指向 byte 数组的指针。但是根据声明的数组大小,我得到不同的结果:

unsafe {

byte[] bytes;

bytes = new byte[1];
fixed(void* pBytes = bytes)
{
((int)pBytes).Dump(); //prints e.g. 41797644
}

bytes = new byte[0];
fixed(void* pBytes = bytes)
{
((int)pBytes).Dump(); //prints 0 ?!
}
}

如果我打开立即窗口并键入 &bytes,我会得到字节数组的实际地址,包括空数组的情况。

为什么 fixed 非托管指针的工作方式不同?

更新:

这是相同的代码以及我从即时窗口中获得的内容:

unsafe {
byte[] bytes;
bytes = new byte[1];
fixed(void* pBytes = bytes)
{
// bytes =>
// {byte[1]}
// [0]: 0
//
// &bytes
// 0x0601c34c //the address of the variable
// bytes: 0x027dc804 //the address of the array
//
// pBytes
// 0x027dc80c // notice pBytes == (&bytes + 8)
// *pBytes: 0
}

bytes = new byte[0];
fixed(void* pBytes = bytes)
{
// bytes =>
// {byte[0]}
//
// &bytes
// 0x0601c34c //same address of the variable, ofc
// bytes: 0x02aa7ad4 //different address of (new) array
//
// pBytes
// 0x00000000 // BOINK
// *pBytes: Cannot dereference 'pBytes'.
// The pointer is not valid.
}
}

数组对象的地址(&bytes)和数组指针之间的 8 字节差异由对象的 header 解释。

内存中的数组表示为:

     type id  size     elem 0   elem1    ...
----|--------|--------|--------|--------|...
^ 4Bytes 4Bytes ^
| `--< pBytes
`--< &bytes

不安全指针实际上指向实际 数据的开始(即,将编码到非托管上下文的内容)

有没有办法在代码中获取空数组的实际地址?

FWIW,我实际上需要它才能到达数组的 header ,以便即时修改数组的运行时类型。

最佳答案

Why doesn't the fixed unmanaged pointer work the same?

这是个奇怪的问题。为什么你认为它应该?

契约是:当你修复一个包含 n 个元素的数组,其中 n > 0 时,你会得到一个指向缓冲区的指针,你可以从中读取和写入 n 个元素。

现在,当 n 为零时,null 是一个指向缓冲区的指针,您可以从中读取和写入零个元素,因此事实证明,对于 n 的情况,该契约(Contract)实际上得到满足为零。 C# 语言不需要这样做。规范说

The behavior of the fixed statement is implementation-defined if the array expression is null or if the array has zero elements.

因此,实现将完全在其权利范围内,例如,在您的程序中抛出异常。 C# 语言规范实际上根本没有定义你的程序的含义。

您正在尝试使用标签外的 fixed 来做一些极其危险和错误的事情。不要那样做。您应该在数组上使用 fixed 仅用于一件事:获取指向您可以读取和写入的 n 个元素的缓冲区的指针。

Is there a way I could get, in code, the actual address of the empty array?

是的。使用 GCHandle 手动固定。

固定托管对象以获取其地址几乎总是危险和错误的。

I need that to be able to get to the array's header, to modify the array's runtime-type on the fly.

那总是危险和错误的。在任何情况下都不要这样做。

关于C#:指向空数组的不安全指针为空?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17091205/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com