0

Here is the mex code I wrote to read in a tab-delimited file. The mex file got created but it causes my MATLAB to end abruptly and give the following error. Can anyone help me where I am going wrong? Please let me know if any further information is required

Abnormal termination: Segmentation violation

#include "mex.h"
#include "matrix.h"
#include <stdio.h>
#include<string.h>
#include<stdlib.h>  
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{   
      FILE *ptr_file;
      const char **field_names;       /* pointers to field names */
      char *buf[1024];
      char *temp[20];
      int count;
      int i, j, k, l;
      int date_field, mva_field, qc_load_field, air_field, qc_air_field, oil_field, qc_oil_field, wind_a_field, qc_wind_a_field, wind_b_field, qc_wind_b_field, wind_c_field, qc_wind_c_field, tamb1_field, qc_tamb1_field;
      char *NAME;
      NAME=mxArrayToString(prhs[0]);
      count = 0;
  //open file to count elements   
      ptr_file =fopen(NAME,"r");
      if (ptr_file != NULL)
      {
  //skip first 3 lines    
      fgets(buf, sizeof(buf), ptr_file);
      fgets(buf, sizeof(buf), ptr_file);
      fgets(buf, sizeof(buf), ptr_file);
  //start counting no. of elements    
      while(fgets(buf, sizeof(buf), ptr_file) != NULL)
          count++;
      fclose(ptr_file);
      }
          field_names[0] = "date";
      field_names[1] = "mva";
      field_names[2] = "qc_load";
      field_names[3] = "air";
      field_names[4] = "qc_air";
      field_names[5] = "oil";
      field_names[6] = "qc_oil";
      field_names[7] = "wind_a";
      field_names[8] = "qc_wind_a";
      field_names[9] = "wind_b";
      field_names[10] = "qc_wind_b";
      field_names[11] = "wind_c";
      field_names[12] = "qc_wind_c"; 
      field_names[13] = "tamb1";
      field_names[14] = "qc_tamb1"; 
      plhs[0] = mxCreateStructMatrix(count, 1, 15, field_names);
      plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
      date_field = mxGetFieldNumber(plhs[0],"date");
      mva_field = mxGetFieldNumber(plhs[0],"mva");
      qc_load_field = mxGetFieldNumber(plhs[0],"qc_load");
      air_field = mxGetFieldNumber(plhs[0],"air");
      qc_air_field = mxGetFieldNumber(plhs[0],"qc_air");
      oil_field = mxGetFieldNumber(plhs[0],"oil");
      qc_oil_field = mxGetFieldNumber(plhs[0],"qc_oil");
      wind_a_field = mxGetFieldNumber(plhs[0],"wind_a");
      qc_wind_a_field = mxGetFieldNumber(plhs[0],"qc_wind_a");
      wind_b_field = mxGetFieldNumber(plhs[0],"wind_b");
      qc_wind_b_field = mxGetFieldNumber(plhs[0],"qc_wind_b");
      wind_c_field = mxGetFieldNumber(plhs[0],"wind_c");
      qc_wind_c_field = mxGetFieldNumber(plhs[0],"qc_wind_c");
      tamb1_field = mxGetFieldNumber(plhs[0],"tamb1");
      qc_tamb1_field = mxGetFieldNumber(plhs[0],"qc_tamb1");
//open file again for storing elements columnwise
    ptr_file =fopen(NAME,"r");
    if (ptr_file != NULL)
    {
//skip first 3 lines    
    fgets(buf, sizeof(buf), ptr_file);
    fgets(buf, sizeof(buf), ptr_file);
    fgets(buf, sizeof(buf), ptr_file);  
//start collecting data 
    for(i=0;i<count;i++){   //increment line
        //get line
        fgets(buf, sizeof(buf), ptr_file);
        j=0;
        k=0;
        //extract first word
        while(buf[j] != '\t'){
            temp[k] = buf[j];
            j++;
            k++;
        }
        temp[k] = '\0';
        j++;
        mxSetFieldByNumber(plhs[0],i,date_field,mxCreateString(temp));
//      strcpy(elem[i].date, temp);
          //extract second word
          k=0;
          while(buf[j] != '\t'){
              temp[k] = buf[j];
              j++;
              k++;
          }
          temp[k] = '\0';
          j++;
  //      elem[i].mva = atof(temp);
          *mxGetPr(plhs[1]) = atof(temp);
          mxSetFieldByNumber(plhs[0],i,mva_field,plhs[1]);    
          //extract third word
          k=0;
          while(buf[j] != '\t'){
              temp[k] = buf[j];
              j++;
              k++;
          }
          temp[k] = '\0';
          j++;
  //      strcpy(elem[i].qc_load, temp);  
          mxSetFieldByNumber(plhs[0],i,qc_load_field,mxCreateString(temp));
  // similarly for other fields of the structure. 
      fclose(ptr_file);
      }
  }
2
Contributors
1
Reply
14
Views
3 Years
Discussion Span
Last Post by Ancient Dragon
0

Line 23: what exactly does sizeof(buf) return? Answer: check line 10 and you will see buf is declared as 1024 pointers, so sizeof(buf) is 1024 * sizeof(char*). Assuming sizeof(char*) == 4 (which it does on MS-Windows and *nix) sizeof(buf) = 1024 * 4 = 4096.

From briefly reading some of the program I suspect line 10 is incorrect, the asterisk shouldn't be there: char buf[1024];

line 9: field_names is also a problem, you use it starting on line 31 but you have never allocated memory for any of those pointers. At that point field_names is nothing more than an unallocated pointer.

line 9 should be like this: char *field_names[15];

Edited by Ancient Dragon

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.