分段错误(核心转储)错误,没有行引用

时间:2015-03-24 10:49:24

标签: c error-handling

我收到"分段错误(核心转储)"错误。这段代码工作得比较早,我正在迷失造成这种情况的原因。任何指针都将非常感激。此错误也不提供行参考。

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

3 个答案:

答案 0 :(得分:2)

这里的问题是,您使用double *Xflat;未初始化。访问未经注册的内存会调用undefined behaviour,而可能会导致分段错误。

在使用之前,您需要将内存分配给double *Xflat;

建议:在编译时启用-g标志,并通过gdb之类的调试器运行二进制文件。大部分时间都会将错误指向特定的行号本身。

答案 1 :(得分:2)

   if (j!=0){
       Xflat[i] = atof(data);
       i++;
        }

这里Xflat未初始化,您正在尝试写入一些未分配的内存,因此行为未定义,您需要在向其写入内容之前为指针分配内存。

答案 2 :(得分:0)

在函数assignX(),

传递的参数nRow和nCol是与实际输入文件内容无关的任意/硬编码值。

Therefore, the code block beginning with 
'for (i=0;i<(nRow*(nCol-1));i++){'  
 has nothing to do with the number of entries 
 saved in the Xflat[] array.

 Therefore, the printf() will either not print all the Xflat[] entries
 or 
 will print from uninitialized memory, 
 resulting in undefined behaviour 
 and can/will lead to a seg fault event. 

suggest: 
1) do not pass the xRow and xCol variables
2) use for( int j=0; j<i; j++ )

There is also the problem that the 'double *Xflat'
does not point to any valid/allocated memory.

suggest:  in main()
double * Xflat = NULL;

and in the assignX() function,
use realloc() and the value 'i+1' 
before each setting of any Xflat[i] offset to a value
which will result in many (expensive) calls to realloc()
An alternative method would be only call realloc()
when all the available 'double' slots are filled
and realloc() use double the current number of 'double' slots
(remembering that the size value would be: sizeof double * numberSlots)

Also, the pointer Xflat is not used anywhere in main() 
so suggest removing from main and from the assignX parameter list
the Xflat declaration can be moved to the assignX function

the main variable 'temp' is not used, so should be eliminated
the main variable 'strL' is only set, but not used
    so should be eliminated

there are some other problems, 
enable all the warnings when compiling.  Then fix the warnings.