C Isogram tests pass locally but fail online

C Isogram tests pass locally but fail online after CLI submission

2/21/23: I appear to currently be having this same issue as issue #56 despite it being a closed issue. Tests pass locally, but fail online after CLI submission. Double checked, it is not a TEST_IGNORE issue. Note that #56 cites the same exercise, Isogram, for the C track.

Submitted files:

isogram.c

#include "isogram.h"

bool is_isogram(const char phrase[])
{
    // Check if NULL
    if (phrase == NULL)
    {
        return false;
    }

    // Create working copy of phrase
    char *input = malloc(strlen(phrase) + 1);
    strcpy(input, phrase);
    
    // Create counter, set to zero
    int counter[26];
    for (int i = 0; i < 26; i++)
    {
        counter[i] = 0;
    }

    // Convert to lowercase
    for (int i = 0; phrase[i] != '\0'; i++)
    {
        input[i] = tolower(phrase[i]);
        if (input[i] != ' ' && input[i] != '-')
        {
            counter[input[i] - 97]++;
        }
        if (counter[input[i] - 97] > 1)
        {
            return false;
        }
    }

    // Free copy
    free(input);

    return true;
}

isogram.h

#ifndef ISOGRAM_H
#define ISOGRAM_H

#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

bool is_isogram(const char phrase[]);

#endif

See local tests here:

Hi. Thanks for posting. It seems there are comments on the GH Issue so I’ll let the conversation continue there, but if it doesn’t get resolved, please post here.

Solved on Github! Shout out to siebenschlaefer catching it! See comment.

for (int i = 0; phrase[i] != '\0'; i++)
    {
        input[i] = tolower(phrase[i]);
        if (input[i] != ' ' && input[i] != '-')
        {
            counter[input[i] - 97]++;
        }
        if (counter[input[i] - 97] > 1) // This accesses memory out of bounds when character is not alphabetical
        {
            return false;
        }
    }

Solution:

for (int i = 0; phrase[i] != '\0'; i++)
    {
        input[i] = tolower(phrase[i]);

        if (input[i] != ' ' && input[i] != '-')
        {
            counter[input[i] - 97]++;
     
            if (counter[input[i] - 97] > 1) 
            {
                return false;
            }
        }
    }
1 Like

I’m not sure if all/most/many of the exercises support this, but I’ve noticed that the makefile provided usually contains a memcheck command, which is helpful for such cases. External tooling like valgrind or clang sanitizers can help you identify many memory-related errors as well. Welcome to the struggle! :slight_smile:

p.s. This is why “It works on my machine!” is never a good answer!

@astyanax I ran memcheck and all the tests passed. I wonder if valgrind would have done a more thorough job. Ideally memcheck would have caught the potential seg fault.

p.s. This is why “It works on my machine!” is never a good answer!

Haha sure. I will say Exercism does request users submit an issue if tests pass locally but fail online after confirming it’s not an IGNORE_TEST issue, hence this post!