1

I'm making a program that reads in text from a file, delimits it into alphanumerical words, and so on. I'm running into an issue where, I've read from the file into a string, and I'm trying to delimit that string into a 2d array where each word is stored in an array. From there I will go on to order them.

However, I am getting a segfault when I malloc for words[n]. For a test file that I'm using, it has ~400 characters. No word is longer than say 10 characters, so (j - i + 1) wouldn't be a huge allocation that might cause a stack overflow (unless I'm misunderstanding my allocation).

I can explain my code for the function if need be, it's a manipulation of a strsplit() function that I wrote.

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

int main(int argc, char** argv) {
    if (argc != 2) {
        printf("Please provide 1 argument.\n");
        return 0;
    }

    FILE *file = fopen(argv[1], "r");
    fseek(file, 0, SEEK_END);
    size_t length = ftell(file); // Getting file size

    char buff, **words, buffer[length + 1];
    int i = 0, j = 0, n = 0, h = 0;

    buffer[length] = '\0';
    rewind(file);
    fread(buffer, 1, length, file); // Read file into buffer, close file
    fclose(file);

    // Deliminate to 2-D array of words
    while (buffer[i] != '\0') {
        while (isalnum(buffer[j]))
            j++;
        i = j;
        while (isalnum(buffer[j]))
            j++;

        words[n] = (char *)malloc(sizeof(char) * (j - i + 1));
        while (i < j)
            words[n][h++] = buffer[i++];

        n += 1, h = 0;
    }
}

It's worth noting that the file input works, and the algorithm to delimit works (it correctly captures the first word from the file from i to j). Do I need to malloc for **words? I don't think that's the issue, but I wouldn't know how many words are in a sample file so I would have to malloc some large amount.

0

1 Answer 1

5

You never actually set the value of words to anything. words needs some memory before you can populate words[n].

You could do char** words = malloc(MAX_NUM_OF_WORDS * sizeof(char*)) or have a stack based collection: char* words[MAX_NUM_OF_WORDS]

Free tip for the day: using file without a NULL check is not good practice.

Sign up to request clarification or add additional context in comments.

5 Comments

Damn, that's what I thought it might be. I didn't want to set some arbitrary MAX_NUM_OF_WORDS but I supposed there's no way around it. And I agree, this program is only in early stages (there's still a lot more to do) and I'm in testing phase, using only a specific file to get my functions working. I'll add in the NULL check. Thanks!
@DanBan you can resize it as you go with realloc
@jenesaisquoi So every time it runs through the loop I realloc and add space for a word before I add it? That wouldn't affect the current contents of it would it?
@DanBan you could do that, but I would limit the system calls by reallocation larger chunks at a time. The contents won't be affected
Either go with a different structure (perhaps a linked list? depends what you want to do with the words at the end). If it really needs to be an array then as @jenesaisquoi says: allocate in "chunks" (pretty much implementing a C++ vector ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.