0

I'm trying to create a function that prints out a sequence of letters in the alphabet in order given a parameter count. For example, if the count was four the output would be strings "a" "ab" "abc" "abcd". However, if the count was more than 26 it would loop around back to 'a', so the output for count 28 would be "a"....."abcdefghijklmnopqrstuvwxyzab". Below is the code I have written. When I try to run this code however I get a segmentation fault error on the line with

out[i][j] = let

and I am having some difficulty figuring out why.

char **sequences(int count) {

    int letter = 0;
    char **out = (char**)calloc(10, sizeof(char*));
    char **array = NULL;

    int size = 0;
    int cap = 10;
    char let;

    for (int i = 0; i < count; i++) {
                
        if (size == cap) {
            cap *= 2;
            array = (char **)realloc(out, cap*sizeof(char *));
            if (array != NULL) {
                out = array;
            } else {
                break;
            }
        }
                
        for (int j = 0; j < i; j++) {
        
            if (letter < 26) {
                let = 97 + letter;
                printf("%c\n", let);
                out[i][j] = let;
                printf("%c\n", out[i][j]);
                letter++;
                size++;
            } else {
                letter = 0;
                let = 97 + letter;
                printf("%c\n", let);
                out[i][j] = let;
                printf("%c\n", out[i][j]);
                letter++;
                size++;
            }
        }
    }
    return out;
}

int main(void) {
   
    char** first;
    char** second;    

    first = sequences(1);
    printf("sequences[0] should be \"a\", got: %s\n", sequences[0]);

    second = sequences(28);
    printf("sequences[27] should be \"ab...yzab\", got: %s\n", sequences[27]);

    return 0;
}
8
  • You're never allocating memory for out[i]. Commented Jun 8, 2022 at 20:40
  • Please put your main() routine where you call the function. More detail you can provide the better. Commented Jun 8, 2022 at 20:41
  • There's no need to keep reallocating out. Just allocate count elements the first time. Commented Jun 8, 2022 at 20:41
  • You're also not modifying size at any point. Commented Jun 8, 2022 at 20:42
  • @jarmod my mistake I forgot to add the increments, they're in there now Commented Jun 8, 2022 at 20:50

3 Answers 3

3

The main problem is that you're never allocating any memory for out[i]. You can do this with calloc(i+1, sizeof(char)). I add 1 for the null terminator.

There's no need to keep growing out with realloc(). You know that the final size will be count, so just allocate that much at the beginning.

You don't need a separate letter counter. You can use modular arithmetic to wrap around at 26.

char **sequences(int count) {
    char **out = malloc(count * sizeof(char*));
    if (out == NULL) {
        abort();
    }

    for (int i = 1; i <= count; i++) {
        out[i-1] = calloc(i+1, sizeof(char));
        if (out[i-1] == NULL) {
            abort();
        }
        for (int j = 0; j < i; j++) {
            char let = 'a' + (j % 26);
            out[i][j] = let;
            printf("%c\n", let);
        }
    }
    return out;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I changed i to start at 1 because we don't want an empty string, but forgot to adjust for this in the array index.
actually making it out[i-1] causes a segmentation fault
Why does that cause a segmentation fault? i-1 should always be in range, since the loop starts at i = 1.
0

The answer is very easy. You allocate an array of pointers, but you do not allocate any space for the strings. As you use calloc all pointers are NULL.

In this line (and in all others where you use out[i][j])

out[i][j] = let;

you dereference NULL pointer. It is Undefined Behaviour (UB) and in your case it is expressing itself as SegFault.

3 Comments

Technically the array elements are zero bytes. That's not necessarily a null pointer.
@Barmar I try to make it simple fo OP - standard defines NULL as (void *)0 or simple zero, then all pointers are NULL.
I know what the standard says. That's a null pointer constant, it doesn't mean that the internal representation is 0.
0

Not sure what the assignment is, but you can forgo the allocations entirely, simply jump straight to the output, which is a bit simpler IMO if that's all you need:

void printSequences(size_t count)
{
    for (size_t i=0; i<count; i++)
    {
        for (size_t j=0; j<=i; j++)
        {
            putchar('a' + (j % 26));
        }
        putchar('\n');
    }
    putchar('\n');
}

Working demo

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.