Thursday, October 13, 2011

malloc() and free()

In C, the malloc() and free() function allows dynamic memory management. However, when using this function with char string (char*), sometimes it is easy to forget padding '\0' after the string:
int main() {
    size_t i;
    char *str1;
    for (i = 0; i < 3; i++)
    {
        str1 = (char*)malloc(10 * sizeof(char));
        memset (str1, 'a', 9-i);
        printf("ADDRESS:0x%x  DATA:%s\n", str1, str1);
        free(str1);
    }
    return 0;
}
And the output might be something like:

ADDRESS:0x4701e0  DATA:aaaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaaa►
ADDRESS:0x4701e0  DATA:aaaaaaaa►

The reason for that whenever free(pointer) is called in the C program, the space pointed by the pointer is collected back in the free mem list which can be reused later by another malloc call. So depending on the mechanism of free(), there is a chance that the content in the part of the memory to which a pointer previously points, was not erased after calling free() (ref here). Then we can see the previous content in the pointer, if no '\0' was padding to the end of str1.


Normally, I choose to add memset after malloc, or pad a '\0' to the end, or use calloc instead, e.g. in the loop:



        str1 = (char*)malloc(10 * sizeof(char));
       
// Option 1. Add memset to set the init values
        //memset (str1, '\0', 10);

        // Option 2. Use calloc() to init to NULL instead
        //str1 = (char*)calloc(10, sizeof(char));

        memset (str1, 'a', 9-i);
        // Option 3. Add the '\0' to the end
        //*(str1+9-i) = '\0';

        printf("ADDRESS:0x%x  DATA:%s\n", str1, str1);
        free(str1);

Then the result will be good:

ADDRESS:0x4701e0  DATA:aaaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaaa
ADDRESS:0x4701e0  DATA:aaaaaaa
















No comments:

Post a Comment

(Coding && Eating) || Sleeping