3

ネイティブ C コードで pin_ptr を使用して配列を渡すと、アクセス違反が発生します。コードは次のとおりです。

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;
}

このコードを変更して、新しいスペースを割り当てて元の配列をそれにコピーすると、アクセス違反が発生しなくなりました。新しいコード:

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;
}

質問: pin_ptr からの使用に問題はありますか?

4

1 に答える 1

3

固定ポインターが範囲外になると、そのオブジェクトを指している、またはそのオブジェクトを指している他の固定ポインターがない限り、そのオブジェクトは固定されているとは見なされなくなります。ポインターを明示的に固定解除する必要はありません。

ドキュメントが言うように、スコープ内にある間pin_ptrのみターゲットを固定します。これは、次のループの各反復の後、オブジェクトの固定が解除され、格納されていたポインターが役に立たなくなることを意味します。

for(i = 0; i < modelsNum; i++)
{
    pin_ptr<unsigned char> ptr = &modelsBuffer[i][0];
    models[i] = (float*) ptr;
}
于 2012-12-21T12:47:38.003 に答える