Ich habe eine Funktion in C geschrieben, die ich in eine Matlab ausführbare (mex-Datei). Die C-Funktion funktioniert einwandfrei, wenn sie einmal von der Matlab-Befehlszeile aus aufgerufen wird. Wenn sie jedoch in einer For-Schleife mehr als 1000 Mal aufgerufen wird, stürzt sie spontan ab. Dies geschieht auch dann, wenn ich bei jeder Iteration der for-Schleife die gleiche Eingabe füttere.Mex aus c-Code erstellt stürzt in Schleife, aber nicht, wenn einmal ausgeführt
Ich fürchte, ich habe einen lauernden C-Bug. ein Problem mit wiederholter Speicherzuweisung, aber ich weiß nicht genug c, um es zu beheben :(
Ich habe das Problem auf die WHILE-Schleife im folgenden Code eingegrenzt (wenn die ganze while-Schleife auskommentiert vor dem Kompilieren des Problems . weggeht) Bitte helfen
#include "mex.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int sum_array(double a[], int from ,int to);
// to compile this code in matlab do: mex -v ranksort.c
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
#define B_OUT plhs[0]
#define A_IN prhs[0]
int i,j,count,M,N; //declare some integers
double *list,*sort_list,*rank_idx,*sort_idx,*ranksOrigOrder;//declare some pointers to doubles which will be allocated dynamically
int *rank_list,*tielocs,*orig_indices;
//set values based on input:
M=mxGetM(A_IN);//get input row num
N=mxGetN(A_IN);//get input col num
if (M>N)
count=M; //get dimensions of A (columns...data must always be in columns)
else
count=N;
list =mxGetPr(A_IN); //grab data from pointer to inputted data
sort_list = calloc(count,sizeof(double)); //allocate size and fill w/zeros all my 'double' arrays
rank_idx =calloc(count,sizeof(double));
sort_idx=calloc(count,sizeof(double));
ranksOrigOrder=calloc(count,sizeof(double));
tielocs =calloc(count+2,sizeof(double));
orig_indices=calloc(count,sizeof(int)); //allocate size and fill w/ zeros all my 'int' arrays
rank_list =calloc(count,sizeof(int));
if (sort_list==NULL||tielocs==NULL||rank_list==NULL||orig_indices==NULL||ranksOrigOrder==NULL||rank_idx==NULL||list==NULL){ puts ("Error (re)allocating memory"); exit (1); }
B_OUT = mxCreateDoubleMatrix(M, N, mxREAL); //create a matlab-style struct for output...
ranksOrigOrder = mxGetPr(B_OUT); // set in-code variable to its pointer
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CODE BODY STARTS HERE ~~~~~~~~~~~~~~~~~~~~*/
/*Calculate the rank for each element in the arr_list*/
for(i=0; i<count; i++){
for(j=0; j<i; j++){
if(list[i] >= list[j])
rank_list[i]++;
else
rank_list[j]++;
}
}
for(i=0; i<count; i++){
sort_list[rank_list[i]] = list[i];
orig_indices[rank_list[i]] =i;
sort_idx[i]=i+1;
}
int tiesIdx=0; int *ties = NULL;
for (i=0; i<count-1;i++){
if (sort_list[i]>= sort_list[i+1]){
ties = (int*) realloc (ties, (tiesIdx) *sizeof(int)); //reallocate size of array
if (ties==NULL){ puts ("Error (re)allocating memory"); exit (1); }
ties[tiesIdx]=i; //add location of tie to newly grown array
tiesIdx++; //found a tie
}
}
// // append 2 after last element to ties
ties = (int*) realloc (ties, (tiesIdx) * sizeof(int));
//reallocate size of array
if (ties==NULL){ puts ("Error (re)allocating memory"); exit (1); }
ties[tiesIdx]=count+1;
tiesIdx++;
int tiecount=0; //step thru all the found ties
// NO IN-LOOP CRASHING if this while loop is commented out....
while (tiecount<tiesIdx){
int tiestart =ties[tiecount]; //grab this tie to check if it is one of a pair or a member of an island of consecutives
int ntied=2;
while (ties[tiecount+1] == ties[tiecount] + 1){ //while it's a consecutive one...
tiecount++;
ntied++;
}
double mysum = (double)sum_array(sort_idx,tiestart,tiestart+ntied)/(double)ntied;
for (int t=tiestart; t<tiestart+ntied;t++){
sort_idx[t]=mysum;
}
tiecount++;
}
for (i=0; i<count;i++){
ranksOrigOrder[orig_indices[i]]=sort_idx[i];
}
free(sort_list);
free(tielocs);
free(rank_list);
free(orig_indices);
free(rank_idx);
free(sort_idx);
return;
}
int sum_array(double a[], int from ,int to){
int i, sum=0;
for (i=from; i<to; i++){
sum = sum + (int)a[i];
}
return(sum);
}
Sie haben ein Speicherleck auf 'rigsOrigOrder', dass es nicht' free() 'ist. – LPs
Verwenden Sie nicht 'puts' /' exit' verwenden Sie stattdessen 'mexErrMsgIdAndTxt'. Verwenden Sie auch 'mxCalloc' und' mxFree' anstelle von 'calloc' und' free'. – Amro