Search code examples
cpointersmallocfreerealloc

Unexpected behavior of string reallocation


I have encountered a strange behavior of memory allocation with string-functions.

Note: right now i am told to ignore failure of the allocation operation.

My code is:

void string_reallocation(char *result, int result_length) {
    char *temp_result = malloc((strlen(result) + 1) * sizeof(char));

    strcpy(temp_result, result);

    realloc(result, (result_length + 1) * sizeof(char));

    strcpy(result, temp_result);

    free(temp_result);
}

this function is called with iterations within a while loop:

    while (current_node != NULL) {
        current_value_to_string = current_node->toStringFunc(current_node->value);
        current_value_length = (int) strlen(current_value_to_string);
        current_length += current_value_length + arrow_length;

        string_reallocation(result, current_length);

        strcat(result, current_value_to_string);
        strcat(result, arrow);

        current_node = current_node->next;
    }

current_node is of type Node as follows:

typedef struct t_node {
    Element value;
    struct t_node *next;
    elementDestroy destroyFunc;
    elementCopy copyFunc;
    elementToString toStringFunc;
} *Node;

The thing is, for some reason, specifically on the third iteration the free(temp_result); fails with a segmentation fault.

I'm don't think that the while loop has anything to do with the segmentation fault but i put it here in case it does.


Solution

  • This is a biphasic solution, since you got to understand how to use realloc(), by checking on its prototype. Let's do just that first.

    Change this:

    realloc(result, (result_length + 1) * sizeof(char));
    

    to this:

    result = realloc(result, (result_length + 1) * sizeof(char));
    

    since from the reference, we got for the prototype of this method:

    Return value: A pointer to the reallocated memory block, which may be either the same as ptr or a new location.


    Now, think about the scope of your variables (pointers). As @whozCraig commented, result = (in the corrected realloc()) assigns a value to an automatic variable. The original result passed in caller-side is unchanged, and now dangling. This has to be handled with an in/out arg or a function return result.

    So what you could do, is to simply return that pointer, by changing this:

    void string_reallocation(char *result, int result_length) {
    

    to that:

    char* string_reallocation(char *result, int result_length) {
      // ...
      return result;
    }
    

    and then change the call to this function, to this:

    result = string_reallocation(result, current_length);