Segmentation fault when assigning a file pointer to another

799 views Asked by At
inline void readSymColValUpdRow(int *row, const int nmat, 
                                int **col, double **val, const int nnz, 
                                FILE *fpcol)
{
  *col = (int*)_mm_malloc(sizeof(int)*nnz, 64);
  *val = (double*)_mm_malloc(sizeof(double)*nnz, 64);
  FILE *fpval;
  *fpval = *fpcol;
   const int BUF_LEN = nnz*10;
   char buf[BUF_LEN];
   fgets(buf, BUF_LEN, fpval);
   fgets(buf, BUF_LEN, fpval);
   ...//other code
}

Here's what I'm trying to do. I need two file pointers referring to different places in a file within the function "readSymColValUpdRow()". Thus I've declared a file pointer *fpval and assign the content of fpcol to it. "fpcol" is a valid file pointer passed by function parameter. I try to make fpval pointing two lines ahead. However, I always get "Segmentation fault" by doing so. Once I comment

*fpval = *fpcol;

and other relevant codes everything's just fine. I don't really understand what's going wrong here. Thank you for your help.

3

There are 3 answers

2
codestation On BEST ANSWER

You are deferencing fpval and the variable is unitialized, this causes the segmentation fault. Also you cannot make a copy of the file pointer that way, you need to make a copy of the underlying file descriptor, for example:

FILE *fpval = fdopen(dup(fileno(fpcol)), "rb");

fileno will obtain the file descriptor, dup will make a duplicate of it and fdopen will open that file descriptor and create the new FILE pointer.

Then close it after you are done with it.

0
Paul R On

fpval is just an uninitialised pointer, hence the crash. But what you're trying to do will not work even if you correctly duplicate the FILE *. Instead you should just maintain two seek positions within the file and use ftell/fseek to switch between the two areas from which you're reading.

0
unwind On

Note that FILE * does not mean that the pointer value represents a position in a file, and that you can treat it as a regular pointer!

It means "pointer to FILE", where FILE is an "object", i.e. a bunch of data fields that are used to represent an open file, which in turn has a current position.

When you do I/O on a file, those fields (or fields even further down) change, but the FILE * pointer value itself doesn't. So you can't copy the FILE * to "save" the position in a file. You must use ftell() and fseek() to jump around in a file.