Search code examples
carraysc-stringsdynamic-allocation

How to dynamically allocate memory for char** in C


How would I go about dynamically allocating memory to char** list in this function?

Basically the idea of this program is I have to read in a list of words from a file. I cannot assume max strings or max string length.

I have to do other stuff with the C-strings but that stuff I should be fine with.

Thanks!

void readFileAndReplace(int argc, char** argv)
{
    FILE *myFile;
    char** list;
    char c;
    int wordLine = 0, counter = 0, i;
    int maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;

    myFile = fopen(argv[1], "r");

    if(!myFile)
    {
        printf("No such file or directory\n");
        exit(EXIT_FAILURE);
    }

    while((c = fgetc(myFile)) !=EOF)
    {
        numberOfChars++;
        if(c == '\n')
        {
            if(maxNumberOfChars < numberOfChars)
                maxNumberOfChars += numberOfChars + 1;

            numberOfLines++;
        }
    }

    list = malloc(sizeof(char*)*numberOfLines);

    for(i = 0; i < wordLine ; i++)
        list[i] = malloc(sizeof(char)*maxNumberOfChars);


    while((c = fgetc(myFile)) != EOF)
    {
        if(c == '\n' && counter > 0)
        {
            list[wordLine][counter] = '\0';
            wordLine++;
            counter = 0;
        }
        else if(c != '\n')
        {
            list[wordLine][counter] = c;
            counter++;
        }
    }
}

Solution

  • Do like this:

    char** list; 
    
    list = malloc(sizeof(char*)*number_of_row);
    for(i=0;i<number_of_row; i++) 
      list[i] = malloc(sizeof(char)*number_of_col);  
    

    Additionally, if you are allocating memory dynamically. you are to free it as work done:

    for(i=0;i<number_of_row; i++) 
      free(list[i] );
    free(list);  
    

    EDIT

    In you revised question:

     int wordLine = 0, counter = 0, i;    
    

    wordLine and counter are 0

    before this code:

    list = malloc(sizeof(char*)*wordLine+1);
    for(i = 0;i < wordLine ; i++)
       list[i] = malloc(sizeof(char)*counter);  
    

    you have to assign value to wordLine and counter variable

    Also memory allocation should be before the following loop(outside):

     while((c = fgetc(myFile)) != EOF){
      :
      :
     }
    

    EDIT:

    New your third version of question. You are reading file two times. So you need to fseek(), rewind() to first char before second loop starts.

    try with:

    fseek(fp, 0, SEEK_SET); // same as rewind()
    rewind(fp);             // same as fseek(fp, 0, SEEK_SET)
    

    also I have doubt in your logic to calculate numberOfLines and maxNumberOfChars. please check that also

    EDIT

    I think your calculation for maxNumberOfChars = 0, numberOfLines = 0 is wrong try like this:

    maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;
    while((c = fgetc(myFile)) !=EOF){
         if(c == '\n'){
             numberOfLines++; 
             if(maxNumberOfChars < numberOfChars)
                 maxNumberOfChars = numberOfChars;
             numberOfChars=0
         }
         numberOfChars++;
    }    
    

    maxNumberOfChars is max number of chars in a line.

    Also change code:

    malloc(sizeof(char)*(maxNumberOfChars + 1));