Search code examples
cpointersmemory-managementfree

Have I created a memory leak in this function?


Trying to improve my C skills. This program should take a string and strip it of whitespace.

I'm aware I've made two calls to malloc but have only called free once. Have I thus got some unfreed memory somewhere, or because I assign the original pointer to the new memory, does it all vanish in the one free call I do make?

Thanks!

static void foo() {
    char *string_to_change = malloc(sizeof(char) * 256);
    strcpy(string_to_change, "my test");
    printf("Before: %s\n", string_to_change); // "my test"
    strip_whitespace(&string_to_change);    
    printf("After: %s\n", string_to_change); // "mytest"
    free(string_to_change);
}

static void strip_whitespace(char **ptr) {
    
    char *res = malloc(strlen(*ptr));
    if (res == NULL)
        exit_with_error(NULL_POINTER);
    int current_pos = 0;

    for (int i = 0; i < strlen(*ptr); i++) {
        if (((*ptr)[i] == ' ') || ((*ptr)[i] == '\n' && ((*ptr)[i-1] == '\n' || (*ptr)[i+1] == '\0'))) {
            continue;
        }
        res[current_pos] = (*ptr)[i];
        current_pos++; 
    }
    res[current_pos] = '\0';
    *ptr = res;
}

Solution

  • You have a leak here:

    *ptr = res;
    

    Prior to this line, *ptr points to an allocated block of memory. You then assign to it the starting address of another allocated block, meaning the original pointer is lost. You should free right before this line:

    free(*ptr);
    *ptr = res;
    

    Also, this allocation is potentially too little:

    char *res = malloc(strlen(*ptr));
    

    If *ptr contains no spaces to strip, res won't have enough memory to hold the terminating null byte. You'll need to add 1 to this.

    char *res = malloc(strlen(*ptr) + 1);