3

When I use pin_ptr to pass an array in native c code, I get access violation. The code is as bellow:

array<float>^ LogLikelihoodScore(array<array<unsigned char>^>^ modelsBuffer , array<float>^ featuresArray, int numberOfFrames)
{
    int i, j, modelsNum = modelsBuffer->Length, len;
    float **models = (float**) malloc(modelsNum * sizeof(void*));
    for(i = 0; i < modelsNum; i++)
    {
        pin_ptr<unsigned char> ptr = &modelsBuffer[i][0];
        models[i] = (float*) ptr;
    }
    array<float>^ scores = gcnew array<float>(modelsNum);
    pin_ptr<float> scoresPtr = &scores[0];
    pin_ptr<float> featuresPtr = &featuresArray[0];
    char* message = CalculateLikelihoodUsingBufferedModels(models, modelsNum, featuresPtr, numberOfFrames, scoresPtr);
    return scores;
}

When I changed this code such that allocate new spaces and copy original array to that, I didn't get access violation. New code:

array<float>^ LogLikelihoodScore(array<array<unsigned char>^>^ modelsBuffer , array<float>^ featuresArray, int numberOfFrames)
{
    int i, j, modelsNum = modelsBuffer->Length, len;
    float **models = (float**) malloc(modelsNum * sizeof(void*));
    for(i = 0; i < modelsNum; i++)
    {
        len = modelsBuffer[i]->Length;
        char* ptr = (char*) malloc(len);
        pin_ptr<unsigned char> ptr2 = &modelsBuffer[i][0];
        memcpy(ptr, ptr2, len);
        models[i] = (float*) ptr;
    }
    array<float>^ scores = gcnew array<float>(modelsNum);
    pin_ptr<float> scoresPtr = &scores[0];
    pin_ptr<float> featuresPtr = &featuresArray[0];
    char* message = CalculateLikelihoodUsingBufferedModels(models, modelsNum, featuresPtr, numberOfFrames, scoresPtr);
    return scores;
}

Question: Are there any problem in my using from pin_ptr?

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 5
    I guess you haven't pin-pointed that problem eh? – Tony The Lion Dec 21 '12 at 12:41
  • You are remarkably lucky to hit this early. If you'd allocated *scores* at the start of the method then you'd have had a really nasty problem with very occasional heap corruption. You still need to fix the memory leak. – Hans Passant Dec 21 '12 at 13:25

1 Answers1

3

When a pinning pointer goes out of scope, the object is no longer considered pinned, unless there are other pinning pointers pointing to or into the object. You do not have to explicitly unpin a pointer.

As the docs say, pin_ptr only pins the target while it is in scope. This means that after each iteration of the following loop, the object is unpinned, rendering the pointers that were stored useless.

for(i = 0; i < modelsNum; i++)
{
    pin_ptr<unsigned char> ptr = &modelsBuffer[i][0];
    models[i] = (float*) ptr;
}
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510