Search code examples
cmallocvalgrindmemset

Uninitialized value was create by a heap allocation if i don't do memset


What im interested in is this.

char *assign_value = (char*)malloc(10 * sizeof(char));
if(strlen(assign_value) == 0) {
    strcpy(assign_value, "A");
} else {
    strcat(assign_value, "A");
}

Basically in the example above i will get error that Uninitialized value was create by a heap allocation. But if i do following thing and insert memset() in between malloc() and if statement i wont see same error. I would like to hear some sugestions, is this the right way, if not, what is right thing to do?

char *assign_value = (char*)malloc(10 * sizeof(char));
memset(assign_value, 0, sizeof(assign_value));
if(strlen(assign_value) == 0) {
    strcpy(assign_value, "A");
} else {
    strcat(assign_value, "A");
}

Thanks!


Solution

  • The problem comes from calling strlen(assign_value) when assign_value is uninitialized, as returned by malloc(10).

    Here are three ways to fix the problem:

    • you can manually set all bytes of the array with memset(assign_value, 0, 10);. Note that your call is incorrect as sizeof(assign_value) evaluated to the size of the pointer, not the size of the array.

    • you can allocate the array with calloc(10, sizeof(char)). calloc returns tha address of a block of memory initialized to all bits zero, which has the same effect as calling memset, but is potentially more efficient.

    • you can set the initial byte to '\0' to make the array an empty string, valid for use with both strcpy and strcat.

    Using calloc() instead of malloc() is a good habit to avoid unpredictable behavior if you fail to initialize any or all of the allocated data before use.

    Note that your code could be simplified radically: if the destination string is indeed empty, calling strcat() is equivalent to strcpy(). You can just write:

    char *assign_value = calloc(10, sizeof(char));
    ...
    strcat(assign_value, "A");
    

    Furthermore, you should verify that strcat() will not cause a buffer overflow by checking the length of the string already stored in the buffer:

    char *assign_value = calloc(10, sizeof(char));
    ...
    if (strlen(assign_value) < 10 - 1) {
        strcat(assign_value, "A");
    } else {
        // handle the error: not enough space in assign_value
    }