2014-01-13 4 views
0

это еще одна проблема, с которой я столкнулся. Прежде всего, я пытаюсь прочитать файл matlab уровня 4, содержащий информацию, экспортированную из PicoScope 6, он считывает четыре массива из файла: A, Tstart, Tinterval и Length. Массив номер один является самым большим на сегодняшний день, он содержит 1000004 значений, однако остальные три содержат только одно значение. Когда я выхожу из кода ниже, он успешно считывает файл, сохраняет его в многомерном массиве, но не работает, когда я пытаюсь использовать массив.EXCEPTION_ACCESS_VIOLATION при использовании большого массива в C

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

В чем причина этого? Когда я запускаю это приложение, он создает minidump. Является ли массив слишком большим?

затруднительного для этого, а также объяснения о том, что неправильно был бы очень признателен!

Заранее благодарен.

ответ

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. В исходном коде все, что вы скопировали, было значением указателя; вы никогда не создавали отдельную копию своих данных.

+0

Спасибо, я попробую! – Linus

Смежные вопросы