Search code examples
cmemory-leaksrealloccalloc

How to realloc some memory allocated using calloc?


I've allocated a string with the calloc function:

//string1 and string2 previously declared
char *stringClone = calloc(strlen(string1) + 1, sizeof(char));

Now I want to do the same thing on stringClone with a different string. Doing:

stringClone = calloc(strlen(string2) + 1, sizeof(char));

I'm gonna have some memory leak, right? How should I use the realloc in this case?


Solution

  • You can use realloc() to reallocate memory allocated by malloc(), calloc(), realloc(), aligned_alloc() or strdup(). Note that if the reallocated block is larger than the original block returned by calloc(), the newly allocated portion will not be initialized to all bits zero.

    Note however that the syntax for realloc() is not what you use: you must pass the pointer as the first argument and a single size_t for the new size. Furthermore, if a new block cannot be allocated, NULL is returned and the block is not freed, hence you should not store the return value directly to stringClone.

    If you want to use realloc(), here is what you should do:

    //string1 and string2 previously declared
    char *stringClone = calloc(strlen(string1) + 1, 1);
    ...
    char *newp = realloc(stringClone, strlen(string2) + 1);
    if (newp == NULL) {
        // deal with out of memory condition
        free(stringClone);
    }
    

    Since you do not seem to care that the contents of stringClone be preserved in the the reallocated block, you should probably simply write:

    //string1 and string2 previously declared
    char *stringClone = calloc(strlen(string1) + 1, 1);
    if (stringClone == NULL) {
        // deal with out of memory condition
        ...
    }
    strcpy(stringClone, string1);
    ...
    free(stringClone);
    stringClone = calloc(strlen(string2) + 1, 1);
    if (stringClone == NULL) {
        // deal with out of memory condition
        ...
    }
    strcpy(stringClone, string2);
    

    Note also that on POSIX compliant systems, there is a memory allocation function that is very useful for your use case: strdup(s) takes a pointer to a C string, allocates strlen(s) + 1 bytes, copies the string to the allocated block and returns it:

    //string1 and string2 previously declared
    char *stringClone = strdup(string1);
    if (stringClone == NULL) {
        // deal with out of memory condition
        ...
    }
    ...
    free(stringClone);
    stringClone = strdup(string2);
    if (stringClone == NULL) {
        // deal with out of memory condition
        ...
    }
    

    Note also that casting the return value of malloc, calloc and realloc is unnecessary in C and considered bad style.