C mex文件中的分段错误
下面是我编写的mex代码,它是在一个以制表符分隔的文件中读取的。创建了mex文件,但它导致我的MATLAB突然结束,并给出以下错误。谁能帮我找出哪里出了问题?如果需要更多信息,请告诉我 异常终止: 分段冲突C mex文件中的分段错误,c,matlab,segmentation-fault,mex,C,Matlab,Segmentation Fault,Mex,下面是我编写的mex代码,它是在一个以制表符分隔的文件中读取的。创建了mex文件,但它导致我的MATLAB突然结束,并给出以下错误。谁能帮我找出哪里出了问题?如果需要更多信息,请告诉我 异常终止: 分段冲突 #include "mex.h" #include "matrix.h" #include <stdio.h> #include<string.h> #include<stdlib.h> void mexFunction(int nlhs,mxArr
#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);
}
}
#包括“mex.h”
#包括“矩阵h”
#包括
#包括
#包括
void MEX函数(int nlhs、mxArray*plhs[]、int nrhs、const mxArray*prhs[])
{
文件*ptr_文件;
常量字符**字段名称;/*指向字段名称的指针*/
char*buf[1024];
字符*温度[20];
整数计数;
int i,j,k,l;
int date_油田、mva_油田、qc_载荷_油田、air_油田、qc_空气_油田、油田、qc_油田、wind_油田、qc_wind_油田、wind_油田、qc_wind_油田、qc_wind_油田、wind_油田、qc_wind_油田、qc_wind_c_油田、tamb1_油田、qc_tamb1_油田;
字符*名称;
NAME=mxArrayToString(prhs[0]);
计数=0;
//打开文件以计数元素
ptr_file=fopen(名称,“r”);
if(ptr_文件!=NULL)
{
//跳过前3行
fgets(buf、sizeof(buf)、ptr_文件);
fgets(buf、sizeof(buf)、ptr_文件);
fgets(buf、sizeof(buf)、ptr_文件);
//开始计算元素的数量
while(fgets(buf、sizeof(buf)、ptr_文件)!=NULL)
计数++;
fclose(ptr_文件);
}
字段名称[0]=“日期”;
字段名称[1]=“mva”;
字段名称[2]=“qc\U加载”;
字段名称[3]=“空气”;
字段名称[4]=“qc\U空气”;
字段名称[5]=“油”;
字段名称[6]=“qc油”;
字段名称[7]=“风a”;
字段名称[8]=“qc\U wind\U a”;
字段名称[9]=“风b”;
字段名称[10]=“qc\U wind\U b”;
字段名称[11]=“wind_c”;
字段名称[12]=“qc\U wind\U c”;
字段名称[13]=“tamb1”;
字段名称[14]=“qc\U tamb1”;
plhs[0]=mxCreateStructMatrix(计数、1、15、字段名称);
plhs[1]=mxCreateDoubleMatrix(1,1,mxREAL);
日期\字段=mxGetFieldNumber(plhs[0],“日期”);
mva_字段=mxGetFieldNumber(plhs[0],“mva”);
qc_加载_字段=mxGetFieldNumber(plhs[0],“qc_加载”);
air_field=mxGetFieldNumber(plhs[0],“air”);
qc_空气_字段=mxGetFieldNumber(plhs[0],“qc_空气”);
油田=mxGetFieldNumber(plhs[0],“油”);
qc_油田=mxGetFieldNumber(plhs[0],“qc_油田”);
风场=mxGetFieldNumber(plhs[0],“风场”);
qc_wind_a_field=mxGetFieldNumber(plhs[0],“qc_wind_a”);
风场=mxGetFieldNumber(plhs[0],“风场”);
qc_wind_b_field=mxGetFieldNumber(plhs[0],“qc_wind_b”);
风场=mxGetFieldNumber(plhs[0],“风场”);
qc_wind_c_field=mxGetFieldNumber(plhs[0],“qc_wind_c”);
tamb1_字段=mxGetFieldNumber(plhs[0],“tamb1”);
qc_tamb1_字段=mxGetFieldNumber(plhs[0],“qc_tamb1”);
//再次打开文件以按列方式存储元素
ptr_file=fopen(名称,“r”);
if(ptr_文件!=NULL)
{
//跳过前3行
fgets(buf、sizeof(buf)、ptr_文件);
fgets(buf、sizeof(buf)、ptr_文件);
fgets(buf、sizeof(buf)、ptr_文件);
//开始收集数据
对于(i=0;i你会得到一个segfault,因为它不是指向某个你可以当作const char*
数组的field\u names
,而是指向任何地方,因为它是未初始化的
const char **field_names; /* pointer to nowhere */
...
field_names[0] = "date"; /* dereferences invalid pointer and BANG */
实际上,你想要的是:
const char *field_names[15]; /* array of pointers to const char */
...
field_names[0] = "date"; /* all is well and good */
...
键C事实:指针不是数组,数组也不是指针,但在某些情况下,数组将隐式转换为指向其第一个元素的指针-因此,将此字段名
数组传递给mxCreateStructMatrix()
而不是常量字符**
仍然是正确的
但是,如果解决了这个问题,您将遇到以下问题:
plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
首先,由于您没有检查nlhs
是否至少为2,plhs[1]
可能不存在,并且在您尝试设置其值时类似地爆炸。IIRC,不检查设置plhs[0]
可能是可以的,因为即使nlhs==0
,plhs[0]
应该指向Ans
而不是显式的输出变量,但实际上,在做任何事情之前检查nlhs
并相应地采取行动是一种很好的做法。同样,不检查nrhs>0而使用prhs[0]
也是不可取的
其次,稍后您将把这个相同的mxArray
分配给多个结构的多个字段,这不是一件有效的事情(并且可能导致Matlab稍后由于堆损坏而崩溃).即使允许,我想你也不希望整个结构数组中的每个数字字段都指向一个被覆盖了n-000次的double
第三,我一点也不太理解plhs[1]
的用法,除非你真的想要强制第二次输出“不管最后读取的数字是什么”。我怀疑你想要的是:
mxArray *mxtmp;
...
/* in parsing loop */
mxtmp = mxCreateDoubleScalar(atof(temp));
mxSetFieldByNumber(plhs[0], i, mva_field, mxtmp);
在其他地方,虽然确实可以在指针中存储char
值,但这不是一件明智或有意义的事情,在这种情况下,显然是另一个错误:
char *buf[1024]; /* array of pointers to char - wrong */
char *temp[20];
char buf[1024]; /* array of char - right */
char temp[20];
你跳过了前三行两次。检查k和j不要超过限制。嗨,丹尼尔,谢谢你的及时回复。我第一次跳过这些行的原因只是为了计算我必须读入的行数,然后下一次完成时只是为了实际读入数据。我已经运行了C代码,它给了我愿望ed outputs。然后我与mexing进行了斗争,因为我以前从未这样做过,在删除了所有格式错误之后,情况就是这样。非常感谢您的帮助。我非常感谢。最初我没有使用plhs[1]是的。但是,你提到的mxtmp,当我使用它时,我经常收到一个错误,说这是非法使用mxArray。是不是我必须声明和我使用mxCreateDoubleScalar的次数一样多的mxArray?@user2971034你不能直接声明mxArray
,因为它是一个不完整的类型-mxtmp
指针,