0

I have an unknown segfault within my print function when I call it in main and I can't see what the obvious fix is. I have put printf's throughout the program and it doesn't print 'here4' making me think it's due to my print function, or when I call it in main.

I want to read a dictionary file into an array of strings.

Here is a snippet of the code:

Any ideas would be greatly appreciated, thanks.

#define PRIME 1009

void fileRead(int argc, char **argv)
    void printTable(int arrayLength, char **table); 

int main(int argc, char **argv)
{
    char **table;
    FILE *fp;
    int i, arrayLength = PRIME;

    /* Initial memory allocation */
    table = (char**)malloc(PRIME*sizeof(char));

    fileRead(argc, argv);
    printf("here3\n");
    for(i = 0; i < arrayLength; i++) {
        printTable(arrayLength,table); 
    }
    printf("here4\n");
    return 0;

}

void fileRead(int argc, char **argv)
{
    FILE *fp;
    char *word;
    int arrayLength = PRIME;

    word = calloc(MAXCHAR, sizeof(char));

    fp = fopen (argv[1], "r");
    printf("here1\n");
    /*read in grid and move along a cell each time */
    while (fscanf(fp, "%s", word)!= EOF) {
        if (argc != (2)) {
            fprintf(stderr, "Cannot open file, %s\n Try again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
        }
        if(fp == NULL) {
            fprintf(stderr, "Cannot open file, %s\n Try again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
            return;
        }
        if (fp == NULL) {
            fprintf(stderr, "Error opening file, try file name dictionary.txt\n");
            exit(EXIT_FAILURE);
        }
    } 
    printf("here2\n");
    fclose(fp);
    return;
}

void printTable(int arrayLength, char **table) 
{
    int i; 
    for(i = 0; i < arrayLength; i++) {  
        printf("%s\n", table[i]);
    }
    printf("\n");
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
odare
  • 19
  • 3
  • 1) `table = (char**)malloc(PRIME*sizeof(char));` --> `table = (char**)malloc(PRIME*sizeof(char*));` 2) `table[i]` isn't initialized. 3) The read word is not stored. – BLUEPIXY Dec 02 '16 at 17:44
  • were you planning to put `word` into `table` somehow – infixed Dec 02 '16 at 17:48
  • Yes, this is a snippet of the whole code but as well as malloc'ing the number of cells within the array, I calloc each cell of the array, so it can handle long words which are read in to the array. This is utilising the word to get the length of the string in the cell. wordLength = strlen(word); – odare Dec 02 '16 at 18:02
  • FYI: [don't cast malloc in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Dec 02 '16 at 18:16
  • Please post a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). Your code can't even compile because of a missing semicolon on line 3. – Barmar Dec 02 '16 at 18:19
  • See http://stackoverflow.com/questions/33047452/definitive-list-of-common-reasons-for-segmentation-faults – Barmar Dec 02 '16 at 18:20
  • it's missing these top lines, it should compile fine with them: #include #include #include #include #define MAXCHAR 25 Or do I need to post the whole code up again? Sorry new to Stack overflow. – odare Dec 02 '16 at 18:25
  • 1
    How will you print the table if you never put `word` into the table? – yLaguardia Dec 02 '16 at 18:28
  • I am attempting to do a hashing program which puts words into the array but just wanted to get the fileread function working first – odare Dec 02 '16 at 18:39
  • The `fileRead()` reads all words, the problem is that you don't do anything with `word` and then you try to print `table[i]` . If you insert `printf("%s ", word);` inside the while loop of your `fileRead()`, you'll see that it reads everything. – yLaguardia Dec 02 '16 at 19:03
  • Ok great, thanks a lot! Once I do get to the stage of wanting to print the array filled with the words, is there an obvious way to do that? – odare Dec 02 '16 at 19:16

2 Answers2

1

Let me summarize your code:

  • you allocate uninitialized memory for table
  • You call a function fileRead():
    • Allocate some memory for word
    • read the file
    • Do nothing with the data read.
    • fileRead() does nothing useful: It does not return anything, it doesn't touch table, is vulnerable to a buffer overflow of word and leaves the memory leak of word behind.
  • And then you printf the unchanged and uninitialized content of table
user5329483
  • 1,260
  • 7
  • 11
1

try this

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

#define PRIME 1009
#define MAXCHAR 256

char **fileRead(FILE *fp, int *len);
void printTable(int arrayLength, char **table); 

int main(int argc, char **argv){
    if (argc != 2) {
        fprintf(stderr, "Need dictionary file argument.\nTry again e.g. %s dictionary.txt\n" , argv[0]);
        exit(EXIT_FAILURE);
    }

    FILE *fp = fopen (argv[1], "r");
    if(fp == NULL) {
        fprintf(stderr, "Cannot open file, %s\nTry again e.g. %s dictionary.txt\n" , argv[1], argv[0]);
        exit(EXIT_FAILURE);
    }

    int arrayLength = PRIME;
    char **table = fileRead(fp, &arrayLength);//fclose(fp) inside this

    printTable(arrayLength, table);

    for(int i = 0; i < arrayLength; ++i)
        free(table[i]);
    free(table);

    return 0;
}

char **fileRead(FILE *fp, int *len){
    char *word = calloc(MAXCHAR, sizeof(char));
    char **table = malloc(*len * sizeof(char*));
    int i = 0;

    while (i < *len && fscanf(fp, "%s", word) != EOF){
        table[i] = malloc(strlen(word)+1);
        strcpy(table[i++], word);
    }
    fclose(fp);
    *len = i;
    free(word);

    return table;
}

void printTable(int arrayLength, char **table){
    int i; 
    for(i = 0; i < arrayLength; i++) {  
        printf("%s\n", table[i]);
    }
    printf("\n");
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70