Search code examples
arrayscpointersscanfc-strings

Scanning and Printing strings using an array of strings


I've created an array of pointers each of which points to a string as follows.

#include <stdio.h>

int main() {
    char *str[4];
    for(int i = 0; i<4; i++)
    {
        scanf("%10s", str[i]);
    }
    puts(""); // not really required
    for(int i = 0; i<4; i++)
    {
        printf("%s\t", str[i]);
    }

    return 0;
}

When I ran it, it compiled successfully. However, when I entered a string, it gave a segmentation fault. Can anyone help with this?

This is what I get when I run the code:

hello (what I input) Segmentation fault (I get this immediately after hitting enter)


Solution

  • char *str[4];
    

    This declares an array[4] of pointers to char whose contents are indeterminate, i.e. they do not point to anything meaningful, and dereferencing them would invoke undefined behavior.

    You have to allocate memory for the pointers like so:

    #include <stdlib.h>
    
    #define MAX_STR_SIZE 11
    
    for (size_t i = 0; i < sizeof str / sizeof *str; ++i) {
        str[i] = malloc(MAX_STR_SIZE);
    
        if (!str[i]) {
            /* Free the previous allocated memory and exit. */
            for (size_t j = i ? i - 1 : i; j >= 0; --j) {
                free(str[j]);
            }
            
            return EXIT_FAILURE;
        }
    }
    

    Note that malloc() returns a null pointer to indicate failure, and the returned pointer must be later passed to free() when the memory is no longer required.

    Or, you could forego dynamically allocating memory and use an array of arrays:

    char str[4][11];
    

    Also note that scanf() returns the number of conversions successfully performed, so its result should also be checked:

    if (scanf("%10s", str[i]) != 1) {
        fputs(/* Error message here. */, stderr);
        return EXIT_FAILURE;
    }
    

    And you can use putchar('\n') to print a newline instead of calling puts() with an empty string.