Search code examples
cmallocvoid-pointers

Correct way to dynamically allocate a const char array in C


I have to read from a file line by line and add those lines into a char array. I need to keep the array const and also pass it as a const pointer.

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

void takeAction(const char **charArray) {

    for (int i = 0; i<2; i++) {
        printf("%s\n", charArray[i]);
    }

}

int main(int ac, char **av)
{
    
    // Read patterns from file

    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int counter = 0;

    const char *charArray[1000];

    fp = fopen(av[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "%s File could not be opened \n", av[2]);
        return 1;
    }
    while ((read = getline(&line, &len, fp)) != -1)
    {
        
        charArray[counter] = malloc(sizeof(char)*(read+1));
        memcpy(charArray[counter], line, read);
        counter++;

        if (counter == 2) {
          counter = 0;
          takeAction(charArray);
        }

    }
    fclose(fp);
    return 0;
}

compilation error

 temp.c: In function ‘main’: temp.c:42:16: warning: passing argument 1
 of ‘memcpy’ discards ‘const’ qualifier from pointer target type
 [-Wdiscarded-qualifiers]
          memcpy(charArray[counter], line, read);
                 ^~~~~~~~~ In file included from temp.c:3:0: /usr/include/string.h:42:14: note: expected ‘void * restrict’ but
 argument is of type ‘const char *’  extern void *memcpy (void
 *__restrict __dest, const void *__restrict __src,

Execution ./temp MyFileWithMultipleLines

When I keep charArray as const, I get warning while memcpy -> ‘memcpy’ discards ‘const’ qualifier

When I remove the const from charArray, I get an error while calling the function takeAction.


Solution

  • You can't have charArray as const as you are writing to it.

    Try something like that:

    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    
    void takeAction(const char **charArray) {
    
        for (int i = 0; i<2; i++) {
            printf("%s\n", charArray[i]);
        }
    
    }
    
    int main(int ac, char **av)
    {
    
        // Read patterns from file
    
        FILE *fp;
        char *line = NULL;
        size_t len = 0;
        ssize_t read;
        int counter = 0;
    
        char *charArray[1000];
    
        fp = fopen(av[1], "r");
        if (fp == NULL) {
            fprintf(stderr, "%s File could not be opened \n", av[2]);
            return 1;
        }
        while ((read = getline(&line, &len, fp)) != -1)
        {
    
            charArray[counter] = malloc(sizeof(char)*(read+1));
            memcpy(charArray[counter], line, read);
            counter++;
    
            if (counter == 2) {
              counter = 0;
              takeAction((const char **)&charArray[0]);
            }
    
        }
        fclose(fp);
        return 0;
    }