C language: reading a txt file and segment fault

AI Thread Summary
The discussion centers on a segmentation fault encountered while running a C program that reads data from a file named "ranked_galaxies.txt". The code compiles and links successfully but produces a blank output file, "f_test.txt", and crashes with a segmentation fault. Key issues identified include improper pointer usage in memory allocation, specifically the incorrect dereferencing of pointers when assigning memory addresses returned by malloc. Additionally, the while loop's condition using feof() is flawed, as it does not account for the failure of fscanf() after the last line is read. The recommended solutions involve correcting pointer assignments and checking the return value of fscanf() to ensure proper reading of data. Ultimately, the problem was resolved by implementing these corrections.
nenyan
Messages
67
Reaction score
0
I use gcc to compile the code. When I run the program, I get segmentation fault (core dumped).


ranked_galaxies.txt:
# PGC Name RA DEC Mass Distance Diameter Tile_Number Rank_stat
37617 NGC3992 179.399700 53.374450 2.290868 22.909000 5.613000 1 2.51796409431e-05
62964 IC4837A 288.817350 -54.132520 1.819701 33.420000 2.946000 3 2.20718986336e-05
37306 NGC3953 178.454250 52.326530 1.235947 17.783000 5.743000 1 1.95861528891e-05



#include <stdio.h>
#include <stdlib.h>
#include <math.h>


/* The function is for readding ranked_Galaxies.txt.*/

int
readrank( FILE *pFile, double **pgc, double **mass, double **distance, double **tile, double **rank)
{
void *pgc1, *mass1, *distance1, *tile1, *rank1;
char *temp, *temp1; /* these two variables can be overwritten. */
int i=0, n=1024; /* n is the buffer. */

if ( !(*pgc=(double *)malloc(n*sizeof(double)))||
!(*mass=(double *)malloc(n*sizeof(double)))||
!(*distance=(double *)malloc(n*sizeof(double)))||
!(*tile=(double *)malloc(n*sizeof(double)))||
!(*rank=(double *)malloc(n*sizeof(double)))||
!(temp=(char *)malloc(n*100)) )
printf("memory error\n");

while (!feof(pFile))
{ fscanf(pFile, "%lf %s %s %s %lf %lf %s %f %f", *pgc+i, temp, temp, temp, mass+i, distance+i, temp, tile+i, rank+i);
i++;
if (i==(n-1)) /*the number of lines is going to be longer than buffer. */
{
if(!(pgc1=realloc(*pgc, 2*n*sizeof(double)))||
!(mass1=realloc(*mass, 2*n*sizeof(double)))||
!(distance1=realloc(*distance, 2*n*sizeof(double)))||
!(tile1=realloc(*tile, 2*n*sizeof(double)))||
!(rank1=realloc(*rank, 2*n*sizeof(double)))||
!(temp1=realloc(temp, 2*n*100))) {
printf("memory error\n"); }
*pgc=pgc1;
*mass=mass1;
*distance=distance1;
*tile=tile1;
*rank=rank1;
temp=temp1;
n*=2; } /*double the buffer*/
}
free(temp);
return i; /* Returning i tell us the accurate number.*/
}


int
main()
{
int i,n2;
double *pgcr, *mass, *distance, *tile, *rank;

FILE *f_rank, *f_rank_test;

if ( !( f_rank_test=fopen("f_test.txt", "w"))) {
printf ("cannot open the f_test.txt file\n");
return 1;}

if ( !( f_rank=fopen("ranked_galaxies.txt", "r"))) {
printf ("cannot open the ranked_galaxies.txt file\n");
return 1;}




n2=readrank(f_rank, &pgcr, &mass, &distance, &tile, &rank);

for (i=0; i<n2; i++)
fprintf(f_rank_test, "%e, %e, %e, %e, %e \n", pgcr, mass, distance, tile, rank); /*check the program. if the codes work well we can get f_rank_test.txt.*/


free(pgcr);
free(mass);
free(distance);
free(tile);
free(rank);


fclose(f_rank);
fclose(f_rank_test);


}
 
Last edited:
Technology news on Phys.org
Help us out here. Are you having problems with this code? If so, are you getting compiler errors or link errors? If the code is compiling and linking without problems, but not producing the correct results, how are the results incorrect?
nenyan said:
ranked_galaxies.txt:
# PGC Name RA DEC Mass Distance Diameter Tile_Number Rank_stat
37617 NGC3992 179.399700 53.374450 2.290868 22.909000 5.613000 1 2.51796409431e-05
62964 IC4837A 288.817350 -54.132520 1.819701 33.420000 2.946000 3 2.20718986336e-05
37306 NGC3953 178.454250 52.326530 1.235947 17.783000 5.743000 1 1.95861528891e-05



#include <stdio.h>
#include <stdlib.h>
#include <math.h>


/* The function is for readding ranked_Galaxies.txt.*/

int
readrank( FILE *pFile, double **pgc, double **mass, double **distance, double **tile, double **rank)
{
void *pgc1, *mass1, *distance1, *tile1, *rank1;
char *temp, *temp1; /* these two variables can be overwritten. */
int i=0, n=1024; /* n is the buffer. */

if ( !(*pgc=(double *)malloc(n*sizeof(double)))||
!(*mass=(double *)malloc(n*sizeof(double)))||
!(*distance=(double *)malloc(n*sizeof(double)))||
!(*tile=(double *)malloc(n*sizeof(double)))||
!(*rank=(double *)malloc(n*sizeof(double)))||
!(temp=(char *)malloc(n*100)) )
printf("memory error\n");

while (!feof(pFile))
{ fscanf(pFile, "%lf %s %s %s %lf %lf %s %f %f", *pgc+i, temp, temp, temp, mass+i, distance+i, temp, tile+i, rank+i);
i++;
if (i==(n-1)) /*the number of lines is going to be longer than buffer. */
{
if(!(pgc1=realloc(*pgc, 2*n*sizeof(double)))||
!(mass1=realloc(*mass, 2*n*sizeof(double)))||
!(distance1=realloc(*distance, 2*n*sizeof(double)))||
!(tile1=realloc(*tile, 2*n*sizeof(double)))||
!(rank1=realloc(*rank, 2*n*sizeof(double)))||
!(temp1=realloc(temp, 2*n*100))) {
printf("memory error\n"); }
*pgc=pgc1;
*mass=mass1;
*distance=distance1;
*tile=tile1;
*rank=rank1;
temp=temp1;
n*=2; } /*double the buffer*/
}
free(temp);
return i; /* Returning i tell us the accurate number.*/
}


int
main()
{
int i,n2;
double *pgcr, *mass, *distance, *tile, *rank;

FILE *f_rank, *f_rank_test;

if ( !( f_rank_test=fopen("f_test.txt", "w"))) {
printf ("cannot open the f_test.txt file\n");
return 1;}

if ( !( f_rank=fopen("ranked_galaxies.txt", "r"))) {
printf ("cannot open the ranked_galaxies.txt file\n");
return 1;}




n2=readrank(f_rank, &pgcr, &mass, &distance, &tile, &rank);

for (i=0; i<n2; i++)
fprintf(f_rank_test, "%e, %e, %e, %e, %e \n", pgcr, mass, distance, tile, rank); /*check the program. if the codes work well we can get f_rank_test.txt.*/


free(pgcr);
free(mass);
free(distance);
free(tile);
free(rank);


fclose(f_rank);
fclose(f_rank_test);


}
 
the code is compiling and linking without problems.But no result. It creat f_test.txt file but the file is blank. and when I run this program. it told me: segmentation fault (core dumped).
 
You are not using your pointers correctly. For example, in the first condition in the first if statement:

Code:
if ( !(*pgc=(double *)malloc(n*sizeof(double)))||
This assignment statement should not have * before pgc, since pgc already is a pointer. You want to store the address returned by malloc (cast as a double *) in pgc. You don't want to store this address at what pgc points at. You'll need to fix the same problem in
12 places, by my count (in both if statements).
 
Also, you should put your code inside [ code] and [ /code] tags (without the leading space). Put a [ code] tag at the top and a [ /code] tag after the last line of your code. I have done that for you, and have also indented your code to make it easier to read.
nenyan said:
I use gcc to compile the code. When I run the program, I get segmentation fault (core dumped).


ranked_galaxies.txt:
# PGC Name RA DEC Mass Distance Diameter Tile_Number Rank_stat
37617 NGC3992 179.399700 53.374450 2.290868 22.909000 5.613000 1 2.51796409431e-05
62964 IC4837A 288.817350 -54.132520 1.819701 33.420000 2.946000 3 2.20718986336e-05
37306 NGC3953 178.454250 52.326530 1.235947 17.783000 5.743000 1 1.95861528891e-05


Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>


/* The function is for readding ranked_Galaxies.txt.*/

int
readrank( FILE *pFile, double **pgc, double **mass, double **distance, double **tile, double **rank)
{
   void *pgc1, *mass1, *distance1, *tile1, *rank1;
   char *temp, *temp1; /* these two variables can be overwritten. */   
   int i=0, n=1024; /* n is the buffer. */

   if ( !(*pgc=(double *)malloc(n*sizeof(double)))||
      !(*mass=(double *)malloc(n*sizeof(double)))||
      !(*distance=(double *)malloc(n*sizeof(double)))||
      !(*tile=(double *)malloc(n*sizeof(double)))||
      !(*rank=(double *)malloc(n*sizeof(double)))||
      !(temp=(char *)malloc(n*100)) )
         printf("memory error\n");

   while (!feof(pFile))
   { 
      fscanf(pFile, "%lf %s %s %s %lf %lf %s %f %f", *pgc+i, temp, temp, temp, mass+i, distance+i, temp, tile+i, rank+i);
      i++;
      if (i==(n-1)) /*the number of lines is going to be longer than buffer. */
      {
         if(!(pgc1=realloc(*pgc, 2*n*sizeof(double)))||
            !(mass1=realloc(*mass, 2*n*sizeof(double)))||
            !(distance1=realloc(*distance, 2*n*sizeof(double)))||
            !(tile1=realloc(*tile, 2*n*sizeof(double)))||
            !(rank1=realloc(*rank, 2*n*sizeof(double)))||
            !(temp1=realloc(temp, 2*n*100))) {
                printf("memory error\n"); }
               *pgc=pgc1;
               *mass=mass1;
               *distance=distance1;
               *tile=tile1;
               *rank=rank1;
               temp=temp1;
               n*=2;
       } /*double the buffer*/
   }   
   free(temp);
   return i; /* Returning i tell us the accurate number.*/
}


int
main()
{
   int i,n2;   
   double *pgcr, *mass, *distance, *tile, *rank;

   FILE *f_rank, *f_rank_test;

   if ( !( f_rank_test=fopen("f_test.txt", "w"))) {
      printf ("cannot open the f_test.txt file\n");
      return 1;
   }

   if ( !( f_rank=fopen("ranked_galaxies.txt", "r"))) {
      printf ("cannot open the ranked_galaxies.txt file\n");
      return 1;
   }

   n2=readrank(f_rank, &pgcr, &mass, &distance, &tile, &rank);

   for (i=0; i<n2; i++)
      fprintf(f_rank_test, "%e, %e, %e, %e, %e \n", pgcr[i], mass[i], distance[i], tile[i], rank[i]); /*check the program. if the codes work well we can get f_rank_test.txt.*/


   free(pgcr);
   free(mass);
   free(distance);
   free(tile);
   free(rank);


   fclose(f_rank);
   fclose(f_rank_test);
}
 
Your while loop is faulty.

After the last line is read from file, feof(fp) will still return false.
But if you read another line, the fscanf() will fail to read proper numbers.
Only then will feof(fp) return true.

I'd recommend checking the return value of fscanf().
 
thank you all. the proble is solved.
 
Back
Top