Search code examples
arrayscstringdynamic-memory-allocation

Dynamically allocate an array of strings


How can I fix this code in a way that it prints the words in the array? Moreover this is the right way to dynamically allocate memory for n words of max size 40?

int main() {

    int n;
    char *arr;
    int i;

    printf("Give me a number:");
    scanf("%d", &n);

    arr = malloc(n * 40);

    for (i = 0; i < n; i++)
    {
        printf("Give me a word: ");
        scanf("%s", &arr[i]);
    }

    for (i = 0; i < n; i++)
    {
        printf("%s", arr[i]); //< --problem here
    }

    return 0;
}

Solution

  • Your allocation is not the best, and printf argument arr[i] expects a char* but you pass it an int (a char if you'd like).

    Here is how you should do it, with comments:

    Live demo

    #include <stdio.h>
    #include <stdlib.h> //for malloc
    
    int main(){
        int n;
        int i;
        
        printf("Give me a number:");
        scanf("%d", &n);
    
        //declare a variable of pointer to pointer to char
        //allocate memory for the array of pointers to char, 
        //each one capable of pointing to a char array
        char **arr = malloc(n * sizeof *arr);
    
        if(arr == NULL){ //check for allocation errors
            perror("malloc");
            return EXIT_FAILURE;
        }
    
        //allocate memory for each individual char array
        for(i = 0; i < n; i++){
            arr[i] = malloc(40); //char size is always 1 byte
    
            if(arr == NULL){ //check for allocation errors
                perror("malloc");
                return EXIT_FAILURE;
            }
        }
    
        for (i = 0; i < n; i++){
            printf("Give me a word: ");
            //limit the size of read input to 39 charaters to avoid overflow, 
            //a nul character will be added by scanf
            scanf("%39s", arr[i]);
        }
    
        for (i = 0; i < n; i++){
            printf("%s\n", arr[i]);
           
        }
         
        for(int i = 0; i < n; i++){ //free the memory for each char array
            free(arr[i]);
        }
        free(arr); //free array of pointers
    
        return 0;
    }
    

    You can also do this with less code using a pointer to array of 40 chars, this will simplify the memory allocation and deallocation:

    Sample with comments:

    Live demo

    #include <stdio.h>
    #include <stdlib.h> //for malloc
    
    int main(){
        int n;    
        int i;
    
        printf("Give me a number:");
        scanf("%d", &n);
    
        //declare a pointer to array of chars and
        //allocate memory for all the char arrays
        char (*arr)[40] = malloc(n * sizeof *arr);
    
        if(arr == NULL){ //check for allocation errors
            perror("malloc");
            return EXIT_FAILURE;
        }
    
        for (i = 0; i < n; i++){
            printf("Give me a word: ");
            scanf("%39s", arr[i]);
        }
    
        for (i = 0; i < n; i++){
            printf("%s\n", arr[i]);
        }
    
        free(arr); //free allocated memory
    
        return 0;
    }