0

I have kind of an issue. I am trying to pin a jagged array (which i am using due to the sheer size of the data i am handling):

    public void ExampleCode(double[][] variables) {
        int nbObservants = variables.Length;

        var allHandles = new List<GCHandle>();
        double*[] observationsPointersTable = new double*[nbObservants];
        double** observationsPointer;
        GCHandle handle;

        for (int i = 0; i < nbObservants; i++) {
            handle = GCHandle.Alloc(variables[i], GCHandleType.Pinned);
            allHandles.Add(handle);
            observationsPointersTable[i] = (double*) handle.AddrOfPinnedObject(); // no prob here
        }

        fixed(double** obsPtr = observationsPointersTable) { // works just fine
            Console.WriteLine("haha {0}", obsPtr[0][0]);
        }

        handle = GCHandle.Alloc(observationsPointersTable, GCHandleType.Pinned); // won't work
        allHandles.Add(handle);
        observationsPointer = (double**) handle.AddrOfPinnedObject();

        // ...

        foreach (var aHandle in allHandles) {
            aHandle.Free();
        }
        allHandles.Clear();
    }

I need to use these double** in multiple parts of my code, and don't really want to explicitly pin them every time I need to use them. It seems to me that, as I can fix them through the usual fixed statement, I should be able to allocate a pinned handle to them.

Is there any way to actually pin a double*[] ?

  • If you have so much data and you find yourself constantly pinning and unpinning it, maybe it's better to move the whole thing into unmanaged code. Or, if you don't change the lengths of the sub-arrays, run them together and remember the lengths/offsets separately. You don't get any bounds checking in unsafe code anyway. – Anton Tykhyy Jan 06 '14 at 09:49
  • That is what i was doing until now, but I am limited, as I am still using .NET 4, and therefore cannot use the massive arrays (it is technically limited to 2GB per array). I also tried memory paged files and non-pinned arrays, but this is prohibitive, performance-wise. – SaigueFault Jan 06 '14 at 10:01
  • I mean really unmanaged code — an external dll in C/C++ or whatever. If your data doesn't fit in 2GB address space, demand a 64-bit platform, that's what it's for. – Anton Tykhyy Jan 06 '14 at 10:26
  • I was referring to http://stackoverflow.com/a/11202075/3164871 As per the unmaged code solution, I am using quite a lot of inbred c# math routines while handling my arrays, which means I'd have to either use a very tricky delegate-based marshalling, or port most of this code to C/C++. I am definitely going beyond the 32-bit address space limitations as **each** of my internal array contains millions of doubles – SaigueFault Jan 06 '14 at 10:49
  • Yeah, I know about the managed array and object size limits. Just port your calculations to C/C++. I think that will be much easier than any other option. The routines in `System.Math` (is that what you meant by 'inbred'?) are standard stuff, there are equivalent routines in `` or ``. – Anton Tykhyy Jan 06 '14 at 12:41
  • Nah, I am using advanced instances of dynamic marshalling and filtering that i implemented on my end to meet some data specific requirements. I am just flabbergasted as I cannot fathom the reason why C# should not be able to pin an array of references. – SaigueFault Jan 06 '14 at 13:55
  • I suppose it's because a jagged array is not a single object. The sub-arrays can be shared — they have a separate existence from the outer array — so it's difficult to decide in advance and for all time what the semantics of pinning a jagged array should be. Also it's very seldom necessary, and a workaround is available for the few cases where it is necessary. – Anton Tykhyy Jan 06 '14 at 20:35
  • Pinning an array of references is fine, you are doing it. If the arrays are large enough then pinning doesn't matter, they will be allocated in the Large Object Heap and won't be moved because they are too large. Getting everything in the LOH (including the outer array) requires an array of at least 10625 x 10625 doubles in 64-bit mode, a gigabyte. – Hans Passant Jan 08 '14 at 12:01

1 Answers1

0

Apparently there is no way to do this. I therefore settled for using fixed statements instead of allocating pinned handles.

  • Can you plz share more details on this, I have gone through such scenario .., ended up using Linked list collection .., I like to know your approach on this – goofyui Aug 08 '19 at 18:42