Search code examples
carraysstringmalloccalloc

Creating an array of strings using malloc in C


I am completely novice in C, and just learned about the dynamic memory allocation using malloc, realloc, calloc and free.

I want to make a small programm which takes an int number as the number of the strings that will be given and then "scanf" them all. Next play with these strings. For example find the most frequent and print it.
For example when i run the programm and type :
5
car house dog tree tree
It should print :
tree 2

I want scanf-printf because this is the input/output methods i am most familiar with at this point.
My code :

int main (){

int N,i,j ;

char *array;

int *freq;


 scanf("%d",&N);

 array = (char*)calloc(N,sizeof(char*));
 for (i=0;i<=N;i++){    
  scanf( ??? );  
 }

 free(array);  
 return 0;  
}

What should i enter in the scanf fuction in order to properly fill the array with strings ? After i fill it will i use something like strcmp and a for loop in order to scan the array and find the most frequent word ? (I can store the frequencies in the *freq)


Solution

  • You want to allocate an array of strings, in other words an array of pointers to characters, and that's exactly what you do allocate. The problem is that you assign the pointer returned by calloc to an array of characters.

    You have two choices here actually: Either change your declaration of array to be an "array" pointers to character, e.g. char **array, and then dynamically allocate the individual strings as well. Something like this

    // Allocate an array of pointers
    char **array = calloc(N, sizeof(*array));
    
    // Allocate and read all strings
    for (size_t i = 0; i < N; ++i)
    {
        // Allocate 50 characters
        array[i] = malloc(50);  // No need for `sizeof(char)`, it's always 1
    
        // Read up to 49 characters (to leave space for the string terminator)
        scanf("%49s", array[i]);
    }
    

    Or you can change the type of array, to be a pointer to fixed-sized "strings", like this

    // Define `my_string_type` as an array of 50 characters
    typedef char my_string_type[50];
    
    // Declare a pointer to strings, and allocate it
    my_string_type *array = calloc(N, sizeof(*array));
    
    // Read all strings from the user
    for (size_t i = 0; i < N; ++i)
    {
        // Read up to 49 characters (to leave space for the string terminator)
        scanf("%49s", array[i]);
    }
    

    Note that I don't cast the result of calloc or malloc. You should never cast void * in C.