0

The program finds the average length of words in a given input and prints the words greater than the average. Here's the program

#define STRING_LEN 80
#define ARRAY_LEN 3
void *emalloc(size_t s) {
    void *result = malloc(s);
    if (NULL == result) {
        fprintf(stderr, "Memory allocation failed!\n");
        exit(EXIT_FAILURE);
    }
    return result;
}


void numbers_greater(char **wordlist, int average, int n){

    if(n < ARRAY_LEN){
        int a = strlen(wordlist[n]);
        if(a>average){ 
            printf("%s", wordlist[n]);
        }
        numbers_greater(wordlist+1, average, n+1);
    }

 }


int main(void) {
    char word[STRING_LEN];
    char *wordlist[ARRAY_LEN];
    int num_words;
    double average;
    int i;

    while (num_words < ARRAY_LEN && 1 == scanf("%79s", word)) {
        wordlist[num_words] = emalloc((strlen(word) + 1) * sizeof wordlist[0][0]);
        strcpy(wordlist[num_words], word);
        num_words++;
    }


    average = 0.0;
    for (i = 0; i < num_words; i++) {
        average += strlen(wordlist[i]);
    }
    average = average / num_words;
    printf("%f\n", average);

    numbers_greater(wordlist, average, 0);



    for (i = 0; i < num_words; i++) {
        free(wordlist[i]);
    }
    return EXIT_SUCCESS;
}

The program works up until the "numbers_greater" method, giving a segmentation fault error. I'm new to C so I'm a little bit confused, the recursive method runs without an error without the strlen statement, but with the strlen statement (even if I set it to a static number like 2) it bombs out of the code. Am I traversing through the array incorrectly?

6
  • 1
    num_words is uninitialized. Commented Jul 31, 2017 at 2:25
  • what is the function print_stuff? Commented Jul 31, 2017 at 2:25
  • Sorry, it's supposed to be numbers_greater (I changed the names of the functions to improve readability) Commented Jul 31, 2017 at 2:29
  • 1
    A segfault often means that you are accessing an invalid pointer somewhere. I suggest that you use a debugger to step through your code to double-check what it is doing. Commented Jul 31, 2017 at 2:29
  • Please edit your question to show the current version of your code. Any inconsistencies will cause much confusion which will only frustrate anyone who wants to help you. It will also waste a lot of your time, not to mention those of us who are willing to help. Commented Jul 31, 2017 at 2:30

2 Answers 2

6

This line

numbers_greater(wordlist+1, average, n+1);

will increment both the wordlist pointer and the integer n. What you are doing, in effect is incrementing the value you are checking by 2 instead of by one, as you would like to do.

To eliminate the segfault, change this line to the following:

numbers_greater(wordlist, average, n + 1);

As a note, this could be done much easier using a simple for loop. Also, I did not read the rest of the code and there may be some other error that I missed, but this should eliminate the segmentation fault in this function.

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

Comments

2

Lets walk through

void numbers_greater(char **wordlist, int average, int n){

    if(n < ARRAY_LEN){
        int a = strlen(wordlist[n]);
        if(a>average){ 
            printf("%s", wordlist[n]);
        }
        numbers_greater(wordlist+1, average, n+1);
    }
}

I have an array of strings that can hold 3 things, and I put n = 1. It works the first time... but now we get to

numbers_greater(wordlist+1, average, n+1);

so now we have an array of strings that can hold 2 things because of the wordlist+1 . n = 2 now , so n < ARRAY_LEN is true, but wordlist[n] will result in reading the 3rd element inside an array that should only hold 2.

To fix this try

numbers_greater(wordlist, average, n+1);

Comments

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.