How to allocate memory for a char * when you don't know its size beforehand

Viewed 62

i have this code :

int main(int ac, char **av)
{
    char *str = malloc(sizeof(char) * 1024);

    if (str == null)
        return (-1);
    if (av[0] != null) {
        strcpy(str, av[0]);
        printf("%s\n", str);
    }
    return (0);
}

i often hear that when i do malloc of sizeof 1024 it's ugly or not a good way to allocate memory, but from what i've learned from my researchs 512 or 1024 for examples are optimized for the processor to do its calculation, so what should i do when i don't know the size of the string i need to handle ? ps: i know in the situation above i could do a strlen of av[0] it's just an illustration of my question.

1 Answers

There a 2 possibles approaches for this problem:

  • you can compute the required size in an initial phase, then allocate the memory and finally use the array.

  • you can keep track of the currently allocated size and reallocate the array as more space is needed along the way. You can call realloc() for that this function is somewhat tricky to use correctly.

Here is a modified version of your example:

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

int main(int ac, char *av[]) {
    if (av[0] != NULL) {
        size_t n = strlen(av[0]) + 1;  // compute required size
        char *str = malloc(sizeof(*str) * n);
        if (str == NULL)
            return 1;
        memcpy(str, av[0], n);
        printf("%s\n", str);
        free(str);
    }
    return 0;
}

Using realloc():

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

int main(int ac, char *av[]) {
    size_t size = 1024;
    char *str = malloc(sizeof(*str) * size);
    if (str == NULL)
        return 1;

    if (av[0] != NULL) {
        size_t n = strlen(av[0]) + 1;  // compute required size
        if (n > size) {
            char *newstr = realloc(str, n);
            if (!newstr) {
                free(str);
                return 1;
            }
            str = newstr;
            size = n;
        }
        memcpy(str, av[0], n);
        printf("%s\n", str);
        free(str);
    }
    return 0;
}

But for this simple case, allocation is not required, char *str = av[0]; would suffice. Yet if you need to allocate a copy of a C string, there is a simpler solution:

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

int main(int ac, char *av[]) {
    if (av[0] != NULL) {
        char *str = strdup(av[0]);
        if (str == NULL)
            return 1;
        printf("%s\n", str);
        free(str);
    }
    return 0;
}
Related