我收到“分段错误(核心转储)”错误。这段代码之前是有效的,我不知道是什么原因造成的。任何指示将不胜感激。此错误也不提供线路参考。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int assignX(int nCol, int nRow, double *Xflat, char *fileName);
int main(){
FILE *f;
char myStr[1000];
int strL;
int nCol;
int nRow;
char *fileName = "reg.dat";
int i, j, k, z, n1=nCol, n2=1, info;
double *Xflat;
double *temp;
f = fopen(fileName, "r");
if (f == NULL) perror ("Error opening file");
else {
if (fgets(myStr, 1000, f) != NULL )
puts(myStr);
fclose(f);
}
strL = strlen(myStr);
nCol = 3;
nRow = 150;
printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);
assignX(nCol, nRow, Xflat, fileName);
return 0;
}
int assignX(int nCol, int nRow, double *Xflat, char *fileName){
int i=0;
int j;
int k=0;
char string[1000];
char* data = NULL;
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof(string), f) != NULL){
data = strtok(string, " ");
for (j=0; NULL != data && j<nCol; j++){
if (data[strlen(data) - 1] == '\n')
data[strlen(data) - 1] = '\0';
if (j!=0){
Xflat[i] = atof(data);
i++;
}
data = strtok(NULL, " ");
}
}
for (i=0;i<(nRow*(nCol-1));i++){
printf("%f\n", Xflat[i]);
}
return 0;
}
这里的问题是,您使用的是未初始化的
double *Xflat;
。访问未初始化的内存会调用未定义的行为,进而可能导致分段错误。
使用前需要给
double *Xflat;
分配内存。
建议:在编译时启用
-g
标志并通过 gdb
等调试器运行二进制文件。大多数时候都会将错误定位到特定的行号本身。
if (j!=0){
Xflat[i] = atof(data);
i++;
}
这里
Xflat
未初始化,您正在尝试写入一些未分配的内存,因此行为未定义,您需要在向指针写入内容之前为指针分配内存。
在函数 allocateX() 中,
传递的参数 nRow 和 nCol 是任意/硬编码值,与实际输入文件内容无关。
因此,以
for (i=0;i<(nRow*(nCol-1));i++){
开头的代码块与Xflat[]
数组中保存的条目数无关。
因此,
printf()
要么不打印所有Xflat[]
条目,要么从未初始化的内存中打印,从而导致未定义的行为,并且可能/将导致段错误事件。
建议:
xRow
和 xCol
变量for( int j=0; j<i; j++ )
还有一个问题是
double *Xflat
没有指向任何有效/分配的内存。main()
double * Xflat = NULL;
并且在
assignX()
函数中,在每次将任何 realloc()
偏移量设置为某个值之前,使用 i+1
和值 Xflat[i]
,这将导致对 realloc()
的多次(昂贵)调用。另一种方法是仅在所有可用的“双”槽都填满时才调用 realloc()
,并且 realloc()
使用当前 double
槽数的两倍(请记住,大小值将是:sizeof double * numberSlots
)
此外,指针
Xflat
不在 main()
中的任何位置使用,因此建议从 main 和 assignX
参数列表中删除。 Xflat 声明可以移至 allocateX 函数
主变量
temp
未使用,因此应消除
主变量strL
仅被设置,但未使用,因此应被消除
还有一些其他问题,请在编译时启用所有警告。 然后修复警告。