Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在c中获取指向数组中间的指针#_C#_.net_Pointers_Bytearray_Memory Pool - Fatal编程技术网

C# 如何在c中获取指向数组中间的指针#

C# 如何在c中获取指向数组中间的指针#,c#,.net,pointers,bytearray,memory-pool,C#,.net,Pointers,Bytearray,Memory Pool,首先,关于我们环境的基本信息:我们在Win7-x64上使用c#.net 4.0,目标是32位 我们有一个预分配的大数组。在函数中,我们希望返回指向该数组中任意点的指针,以便调用函数可以知道在何处写入。例: class SomeClass { void function_that_uses_the_array() { Byte [] whereToWrite = getEmptyPtrLocation(1200); Array.Copy(sourceArray,

首先,关于我们环境的基本信息:我们在Win7-x64上使用c#.net 4.0,目标是32位

我们有一个预分配的大数组。在函数中,我们希望返回指向该数组中任意点的指针,以便调用函数可以知道在何处写入。例:

class SomeClass {
    void function_that_uses_the_array() {
       Byte [] whereToWrite = getEmptyPtrLocation(1200);
       Array.Copy(sourceArray, whereToWrite, ...);
    }
}

class DataProvider {
    int MAX_SIZE = 1024*1024*64;
    Byte [] dataArray = new Byte[MAX_SIZE];
    int emptyPtr=0;
    Byte[] getEmptyPtrLocation(int requestedBytes) {
       int ref = emptyPtr;
       emptyPtr += requestedBytes;
       return dataArray[ref];
    }
}
本质上,我们希望预先分配一大块内存,并保留该内存块的任意长度部分,让其他类/函数使用该部分内存

在上例中,GetEmptyPterLocation函数不正确;它被声明为返回字节[],但正在尝试返回单字节值


谢谢

不进入非托管代码,不能返回指针到C数组中的中间,只能返回要输入数据的数组索引。

这是C++不C++。在C语言中内存分配一般都很快,而且不存在内存碎片,这是C++中预分配的主要原因之一。p> 话虽如此,但您仍然希望这样做,我将只使用数组索引和长度,因此您可以使用
array.Copy
在该位置写入

编辑:


正如其他人所指出的那样,
ArraySegment
更适合您的需要:它将消费者限制在其阵列的某个部分,并且不需要在更新原始阵列中的内容(如ArraySegment所示)之前分配单独的阵列。

正如其他人所说,你不能在C#中这样做,一般来说,你不应该这样做。使用系统-利用垃圾收集器等


话虽如此,如果您想做类似的事情,并且您可以信任您的客户机不会超出其分配的时间段,那么您可以让您的方法返回,而不是
byte[]
。这将代表“数组的一部分”。显然,.NET中的大多数方法都不使用ArraySegment,但您可以编写扩展方法,将其用作您想要使用的一些更常见操作的目标。

如果必须这样做,您的选项包括返回ArraySegment(正如Jon Skeet指出的),或使用流。可以使用构造函数返回作为数组子集的MemoryStream。您需要将所有的内存读写操作作为流操作来处理,而不是作为偏移操作来处理。

这篇文章很老,但我有一个简单的解决方案。我发现这个问题有很多答案,比如“你不应该”。如果有方法做某事,为什么不使用它呢

但除此之外,你可以使用以下方法

int[] array = new int[1337];
position = 69;
void* pointer = (void*)Marshal.UnsafeAddrOfPinnedArrayElement(array, position);

就情绪达成一致(不应这样做),不同意使用Array.Copy。分配新内存时,它不会返回数组的子集。来自MSDN:@Chris:Agreed-Array.Copy将要求使用它的类在将其复制到目标缓冲区之前分配自己的缓冲区,并且他们将有权访问完整的数组-因此,最好使用
ArraySegment
。@jon,@Chris,@BrokenGlass:感谢关于ArraySegment的信息,我第一次听说这门课。尽管如此,它似乎不是很有用。事实证明,不能使用[]为ArraySegment编制索引,也不能对其进行迭代。显然,您必须访问ArraySegment.Array字段,然后使用[]对其进行索引,索引ID为原始数组索引!。这是一个很好的例子,我曾多次听到垃圾收集器的争论,但我们到目前为止的测试表明,预分配确实有帮助。它是否会非常依赖于应用程序的特性?在我们的应用程序中,我们需要以每秒250次左右的速度分配/释放2K-128K内存(每次大小不同)。@SomethingBetter:您是否考虑过预分配不同大小的完整数组,并允许调用方只获得不同大小的缓冲区,而不是一个大数组中的子数组?也许,但长度差异很大,会导致大量碎片/空白。实际上,我的一个基本问题是,我无法将数据读入数组中的任意位置,因为我们使用的是第三方库。我在这里发布了另一个问题:。如果有任何见解,我将不胜感激--thanks@SomethingBetter:对于这样的API,不将索引引入数组(如Stream.Read)是相对不常见的。就你的碎片问题而言——如果你有“带”的缓冲区,它不需要有太多的影响。您可以在不浪费大量空间的情况下浪费一些空间。