Reason for segfault in C program?

hi everyone im working on a program so far and I've gotten the dreaded segmentation fault which I always seem to get. I've run gdb and backtraced it to fgets in main. What am i doing wrong? Any help is greatly appreciated!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "intList.h"
#include "intList.c"

typedef struct Edge {
   int from, to;
   double weight;
}Edge;

IntList* initedges(int n){
   IntList* adjvertices = calloc(n+1,sizeof(IntList));
   int itora;
   for( itora = 0; itora <= n; itora++){
      adjvertices[itora] = NULL;
   }
   return (adjvertices);
}

Edge parseedge(char* line){
   Edge newedge;
   int nwords = sscanf(line, " %d %d %f",&newedge.from, &newedge.to, &newedge.weight);
   if(nwords < 2 || nwords > 3){
      char tempo[1024];
      perror(strcat(strcpy(tempo,"Bad edge: "), line));
      exit(1);
   }
   if (nwords == 2) newedge.weight = 0.0;
   return newedge;
}

int parsen(char* line){
   int n;
   if(sscanf(line, "%i", &n) != 1){
      char temp[1024];
      perror(strcat(strcpy(temp, "Bad line 1: "), line));
      exit(1);
   }
   return n;
}

int loadedges(FILE* inbuf, IntList* adjvertices){
   Edge newele;
   int m = 0;
   char *line;
   fgets(line, sizeof(line), inbuf);
   while(line!=NULL){
      newele = parseedge(line);
      adjvertices[newele.from] = cons(newele.to, adjvertices[newele.from]);
      ++m;
      fgets(line, sizeof(line), inbuf);
   }
   return m;
}


int main(int argc, char* argv[]){
   int a, b;
   IntList* adjvert;
  
   if(argc == 0){
      printf("Usage: graph < input.data");
      exit(0);
   }

   char *infile= argv[2];
   FILE *inbuf = fopen(infile, "r");
   printf("Opened %s for input.", infile);
   char line[1024];
   fgets(line, 1024, inbuf);
   b = parsen(line);
   printf("n = %d", b);

   adjvert = initedges(b);
   a = loadedges(inbuf, adjvert);
   fclose(inbuf);
   printf("m = %d", a);
   
   int itor;
   for(itor = 0; itor<=b; itor++){ 
     printf("%d\t%s", itor, tostring(",",adjvert[itor])); 
   }
}
I didn't look that close, but I did notice some weirdness:

line 62, 67: argc is never zero. It always has to at least be 1. Remember:

argv[0] = program name (usually)
argv[1] = first parameter
argv[2] = second parameter
... etc

So if you need the program to be called with at least 1 parameter, then argc must be >= 2, and you want to use argv[1], not argv[2].


I find it unlikely that that would cause a segfault though.

Hi Disch,

Thanks for taking the time to reply. I did change argv[2] to argv[1] as the input file directly following the program name is what i wanted but that didnt fix the problem. After digging deeper I found that it is a problem with inbuf on line 68. I suspect that fopen is not giving me what I want and causes fgets to be called with a random pointer causing a segfault.
fopen returns a null pointer when it fails. You're not checking that anywhere.
And how did you expect the following to work?
1
2
char *line;
fgets(line, sizeof(line), inbuf);
Athar,

Just noticed that issue and tried putting

if (inbuf != NULL)

before line 68 which fixes the problem. However, now I am getting a seg fault
at the fgets in function loadedges although i do not know which one. I have added a check for inbuf in loadedges as well but the result is the same.

i hate seg faults.
However, now I am getting a seg fault
at the fgets in function loadedges although i do not know which one.

See the second part of my previous post.
Ah sorry, i mustve forgotten to respond to your second part in my frustration. On the reference page for fgets on this site, it says that fgets is to be used
in this manner

char * fgets ( char * str, int num, FILE * stream );

with "...in the string copied to str." in this description. I took this to mean that whatever fgets returns, it returns to the first parameter. In essence, I expect line to contain the contents of the user specified file (should be a .txt file with numbers as well as whitespace,newline).

I tried char *line2 = fgets
Last edited on
line is an uninitialized pointer which is pointing to some random location in memory.
It is supposed to point to a buffer where fgets can store the data.
Topic archived. No new replies allowed.