### 在C＃中从锯齿状数组转换为双指针

e.g。将`double[][]`转换为`double**`

#### 3 个答案:

``````unsafe
{
double[][] array = new double[3][];
array[0] = new double[] { 1.25, 2.28, 3, 4 };
array[1] = new double[] { 5, 6.24, 7.42, 8 };
array[2] = new double[] { 9, 10.15, 11, 12.14 };

GCHandle[] pinnedArray = new GCHandle[array.Length];
double*[] ptrArray = new double*[array.Length];

for (int i = 0; i < array.Length; i++)
{
pinnedArray[i] = GCHandle.Alloc(array[i], GCHandleType.Pinned);
}

for (int i = 0; i < array.Length; ++i)
{
// as you can see, this pointer will point to the first element of each array
}

fixed(double** doublePtr = &ptrArray[0])
{
Console.WriteLine(**doublePtr);
}

// unpin all the pinned objects,
// even if they will went out of scope
for (int i = 0; i < pinnedArray.Length; ++i)
pinnedArray[i].Free();
}
``````

``````for(int i = 0; i < 1000000; ++i)
{
MemoryStream stream = new MemoryStream(10);
//make sure that JIT will not optimize anything, make some work
stream.Write(new Byte[]{1,2,3}, 1, 2);
}
GC.Collect();
``````

``````namespace DangerousNamespace
{
// WARNING!
// This code includes possible memory access errors with unfixed/unpinned pointers!
public class DangerousClass
{
public static void Main()
{
unsafe
{
double[][] array = new double[3][];
array[0] = new double[] { 1.25, 2.28, 3, 4 };
array[1] = new double[] { 5, 6.24, 7.42, 8 };
array[2] = new double[] { 9, 10.15, 11, 12.14 };

fixed (double* junk = &array[0][0])
{
double*[] arrayofptr = new double*[array.Length];
for (int i = 0; i < array.Length; i++)
fixed (double* ptr = &array[i][0])
{
arrayofptr[i] = ptr;
}

for (int i = 0; i < 10000000; ++i)
{
Object z = new Object();
}
GC.Collect();

fixed (double** ptrptr = &arrayofptr[0])
{
for (int i = 0; i < 1000000; ++i)
{
using (MemoryStream z = new MemoryStream(200))
{
z.Write(new byte[] { 1, 2, 3 }, 1, 2);
}
}
GC.Collect();
// should print 1.25
Console.WriteLine(*(double*)(*(double**)ptrptr));
}
}
}
}
}
}
``````

double [] []是double []的数组，而不是double *，所以要获得双**，我们首先需要一个double * []

``````double[][] array = //whatever
//initialize as necessary

fixed (double* junk = &array[0][0]){

double*[] arrayofptr = new double*[array.Length];
for (int i = 0; i < array.Length; i++)
fixed (double* ptr = &array[i][0])
{
arrayofptr[i] = ptr;
}

fixed (double** ptrptr = &arrayofptr[0])
{
//whatever
}
}
``````

``````public static double** ToPointer(this double[][] array)
{
fixed (double* arrayPtr = array[0])
{
double*[] ptrArray = new double*[array.Length];
for (int i = 0; i < array.Length; i++)
{
fixed (double* ptr = array[i])
ptrArray[i] = ptr;
}

fixed (double** ptr = ptrArray)
return ptr;
}
}
``````