0

これは私が立ち往生している別の問題です。まず、PicoScope 6 からエクスポートされた情報を含むレベル 4 の matlab ファイルを読み込もうとしています。ファイルから A、Tstart、Tinterval、Length の 4 つの配列を読み込みます。配列番号 1 は群を抜いて最大で、1000004 個の値が含まれていますが、他の 3 つにはそれぞれ 1 つの値しか含まれていません。以下のコードを実行すると、ファイルが正常に読み取られ、多次元配列に格納されますが、配列を使用しようとすると失敗します。

#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <matio.h>
#include "ReadMatFile.h"

//macros
#define getLength(x)  (sizeof(x) / sizeof(x[0]))

//variables
double *dataMatrix[4];
int innerSize[getLength(dataMatrix)];

//functions
jobjectArray convertToArray(JNIEnv *env, double **data, int length1D,
        int *length2D);

JNIEXPORT jdoubleArray JNICALL Java_ReadMatFile_readMatFile(JNIEnv *env,
        jobject object, jstring str) {
    const char *fileName = (*env)->GetStringUTFChars(env, str, 0);
    mat_t *matfp;
    matvar_t *matvar;
    matfp = Mat_Open(fileName, MAT_ACC_RDONLY | MAT_FT_MAT4);
    if ( NULL == matfp) {
        fprintf(stderr, "Error opening MAT file %s\n", fileName);
        return NULL;
    }
    int i = 0;
    while ( NULL != (matvar = Mat_VarReadNext(matfp))) {
        double *data = (double*) (matvar->data);
        dataMatrix[i] = data;
        innerSize[i] = (int) matvar->nbytes / matvar->data_size;
        Mat_VarFree(matvar);
        matvar = NULL;
        i++;
    }
    Mat_Close(matfp);
    (*env)->ReleaseStringUTFChars(env, str, fileName);
    int s;
    for(s = 0; s < innerSize[0]; s++)
        printf("A[%d] = %e\n", s, dataMatrix[0][s]); /* Fails here */
    return NULL;
    //return convertToArray(env, dataMatrix, getLength(dataMatrix) ,innerSize);
}

jobjectArray convertToArray(JNIEnv *env, double **data, int length1D,
        int *length2D) {
    jsize outerSize = (jsize) length1D;
    jclass class = (*env)->FindClass(env, "[D");
    jobjectArray outer = (*env)->NewObjectArray(env, outerSize, class, 0);
    jsize i;
    for (i = 0; i < outerSize; i++) {
        jsize innerSize = (jsize) length2D[i];
        jdoubleArray inner = (*env)->NewDoubleArray(env, innerSize);
        (*env)->SetDoubleArrayRegion(env, inner, 0, innerSize, data[i]);
        (*env)->SetObjectArrayElement(env, outer, i, inner);
        (*env)->DeleteLocalRef(env, inner);
    }
    return outer;
}

これの原因は何ですか?このアプリケーションを実行すると、ミニダンプが作成されます。配列が大きすぎませんか?

これの修正と、何が間違っているかの説明をいただければ幸いです。

よろしくお願いします。

4

1 に答える 1

2

問題は次のコードにあると思われます。

double *data = (double*) (matvar->data);
dataMatrix[i] = data;
innerSize[i] = (int) matvar->nbytes / matvar->data_size;
Mat_VarFree(matvar); // whoopsie

Mat_VarFreeが思っていることがmatvar->data有効なポインターでdataMatrix[i]はなくなった場合、つまり、有効なポインターではなくなったため、クラッシュします。

あなたがやろうとしていることは、

innerSize[i] = matvar->nbytes / matvar->data_size;
dataMatrix[i] = malloc( sizeof *dataMatrix[i] * innerSize[i] );
if ( dataMatrix[i] )
  memcpy( dataMatrix[i], matvar->data, matvar->nbytes );
Mat_VarFree( matvar );

つまり、 でデータのローカル コピーを作成し、matvar->dataそれを に保存しますdataMatrix。元のコードでは、コピーしたのはポインター値だけでした。データの別のコピーを作成したことはありません。

于 2014-01-13T20:58:30.027 に答える