arrays - What is the cause of my segment fault in C? -


when compile code, no errors. however, when attempt run it, segmentation fault (core dumped). here main:

original code

void main(int argc, char *argv[]){     if(argc < 3){           return;     }      char *stop_list_name = argv[1];     char *doc_names[argc - 2];      int i;     for(i = 0; < argc; i++){             doc_names[i] = argv[i];     }  //create array of stop words     char *stopwords[50];     char *word;     int word_counter = 0;     file *fp;     fp = fopen(stop_list_name, "r");     if(fp != null){             while(!feof(fp)){                     fscanf(fp, "%s", word);                     stopwords[word_counter] = word;                     word_counter++;             }     }      fclose(fp);      for(i = 0; stopwords[i] != '\0'; i++){             printf("%s", stopwords[i]);     } } 

i'm pretty sure wrong in while loop, don't know what, or how fix it.

amended code

after seeing answers, modified code looks this, still crashes. what's wrong now?

int main(int argc, char *argv[]){     if(argc < 3){             return;     }      char *stop_list_name = argv[1];     char *doc_names[argc - 2];      int i;     for(i = 2; < argc; i++){             doc_names[i-2] = argv[i];     }  //create array of stop words     enum {max_stop_words = 50};     char *stopwords[max_stop_words];     int word_counter = 0;     file *fp = fopen(stop_list_name, "r");     if(fp != null){             char word[64];             int i;             for(i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++){                     stopwords[i] = strdup(word);             }              word_counter = i;             fclose(fp);     }      for(i = 0; stopwords[i] != '\0'; i++){             printf("%s", stopwords[i]);     } } 

problems in original code

one possible source of problems is:

char *doc_names[argc - 2];  int i; for(i = 0; < argc; i++){         doc_names[i] = argv[i]; } 

you allocate space argc-2 pointers , proceed copy argc pointers space. that's buffer overflow (in case, stack overflow too). can cause trouble. plausible fix is:

for (i = 2; < argv; i++)     doc_names[i-2] = argv[i]; 

however, don't need copy argument list; can process arguments index 2 end. note code shown doesn't use doc_names, out-of-bounds assignment can still cause trouble.


you not allocating space read word into, nor allocating new space each stop word, nor ensure not overflow bounds of array in you're storing words.

consider using:

enum { max_stop_words = 50 }; char *stopwords[max_stop_words]; int word_counter = 0; file *fp = fopen(stop_list_name, "r"); if (fp != null) {     char word[64];     (i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++)         stopwords[i] = strdup(word);     word_counter = i;     fclose(fp); } 

this diagnosed problem plausible cause of crash. used i (declared earlier in code) in loop because word_counter makes loop control line long so.

strictly, strdup() not part of standard c, part of posix. if don't have posix, can write own:

#include <stdlib.h> #include <string.h>  char *strdup(const char *str) {     size_t len = strlen(str) + 1;     char *result = malloc(len);     if (result != 0)         memmove(result, str, len);     return result; } 

you have other bad practices on display:


problems in amended code

there's 1 important , couple of minor problems in amended code:

  • your loop prints stop words depends on null pointer (curiously spelled '\0' — valid unconventional spelling null pointer), initialization code doesn't set null pointer.

    there (at least) 2 options fixing that:

    1. add null pointer:

         (i = 0; < max_stop_words-1 && fscanf(fp, "%63s", word) == 1; i++)        stopwords[i] = strdup(word);     stopwords[i] = 0;    fclose(fp); }  (i = 0; stopwords[i] != '\0'; i++)     printf("%s\n", stopwords[i]); 

      note upper bound max_stop_words - 1.

    2. or can use wordcount instead of condition:

      for (i = 0; < wordcount; i++)     printf("%s\n", stopwords[i]); 

    i'd choose second option.

  • one reason doing avoids warnings wordcount being set , not used — minor problem.

  • and doc_names set not used.

i worry because default compiler options generate errors unused variables — code doesn't compile until fix it. leads to:

#include <stdio.h> #include <string.h>  int main(int argc, char *argv[]) {     if (argc < 3)     {         fprintf(stderr, "usage: %s stop-words docfile ...\n", argv[0]);         return 1;     }      char *stop_list_name = argv[1];     char *doc_names[argc - 2];      int i;     (i = 2; < argc; i++)     {         doc_names[i - 2] = argv[i];     }     int doc_count = argc - 2;      // create array of stop words     enum { max_stop_words = 50 };     char *stopwords[max_stop_words];     int word_counter = 0;     file *fp = fopen(stop_list_name, "r");     if (fp != null)     {         char word[64];         int i;         (i = 0; < max_stop_words && fscanf(fp, "%63s", word) == 1; i++)             stopwords[i] = strdup(word);          word_counter = i;         fclose(fp);     }      (i = 0; < word_counter; i++)         printf("stop word %d: %s\n", i, stopwords[i]);      (i = 0; < doc_count; i++)         printf("document %d: %s\n", i, doc_names[i]);      return 0; } 

and, given stop words file containing:

help able may can should antonym prozac 

and compiling (source file sw19.c, program sw19) with:

$ gcc -o3 -g -std=c11 -wall -wextra -wmissing-prototypes -wstrict-prototypes \ >     -wold-style-definition -werror sw19.c -o sw19 

and running as:

$ ./sw19 stopwords /dev/null stop word 0: stop word 1: able stop word 2: may stop word 3: can stop word 4: stop word 5: should stop word 6: stop word 7: antonym stop word 8: prozac document 0: /dev/null $