Home > Mobile >  Allocating and deallocating memory using free() inside a function in C
Allocating and deallocating memory using free() inside a function in C

Time:09-14

I am just unable to figure out how to release the memory I have allocated inside a function.

#include <stdio.h>
#include <stdlib.h>

typedef struct node node_t;

struct node {
    int data;
    node_t* next;
};

void insert(node_t** head, int data) {

    node_t* temp = malloc(sizeof(node_t));
    node_t* ptr;

    temp->data = data;
    temp->next = NULL;

    if (*head == NULL) {
        *head = temp;
    } else {
        ptr = *head;

        while(ptr->next != NULL) {
            ptr = ptr->next;
        }
        ptr->next = temp;
    }

}

node_t* arrayToLL(int *arr, int size) {
    node_t* head = NULL;

    for(int i=0; i<size; i  ) {
        insert(&head, arr[i]);
    }

    return head;
}

void printList(struct node* head) {
    while (head->next!=NULL) {
        printf("%d -> ", head->data);
        head = head->next;
    }
    printf("%d\n", head->data);
}


int main() {

    int arr[] = {1, 2, 3, 4};
    int size = sizeof(arr)/sizeof(arr[0]);

    node_t* head = NULL;

    head = arrayToLL(arr, size);

    printList(head);

    free(head);
    head = NULL;

    return 0;
}

If I run it with gcc main.c -fsanitize=address -o main && ./main then it warns me about memory leaks like below,

1 -> 2 -> 3 -> 4

=================================================================
==775653==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x7f675ceb4867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55b502d672c5 in insert (/home/altair/linkedlist/main 0x12c5)
    #2 0x55b502d6753a in arrayToLL (/home/altair/linkedlist/main 0x153a)
    #3 0x55b502d67887 in main (/home/altair/linkedlist/main 0x1887)
    #4 0x7f675ca29d8f  (/lib/x86_64-linux-gnu/libc.so.6 0x29d8f)

Indirect leak of 48 byte(s) in 3 object(s) allocated from:
    #0 0x7f675ceb4867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55b502d672c5 in insert (/home/altair/linkedlist/main 0x12c5)
    #2 0x55b502d6753a in arrayToLL (/home/altair/linkedlist/main 0x153a)
    #3 0x55b502d67887 in main (/home/altair/linkedlist/main 0x1887)
    #4 0x7f675ca29d8f  (/lib/x86_64-linux-gnu/libc.so.6 0x29d8f)

SUMMARY: AddressSanitizer: 64 byte(s) leaked in 4 allocation(s).

I know that the head pointer I have allocated inside arrayToLL(int *arr, int size) can be released by free(head) from the main function. But what about the *temp and *ptr inside insert(node_t** head, int data). And I am guessing these not released allocated memory is causing the memory leaks.

My question is how to free the pointer memory I have allocated inside a void function or at least how to avoid those memory leaks?

CodePudding user response:

I know that the head pointer I have allocated inside arrayToLL(int *arr, int size) can be released by free(head) from the main function.

In your program, all dynamic memory allocation occurs in arrayToLL(), but none occurs directly in that function. Only function insert() calls malloc() directly.

But what about the *temp and *ptr inside insert(node_t** head, int data).

It is not about the variables that store pointers to the allocated space, as you should already know based on your remarks about head. It is about pointer values, whatever variable they happen to be stored in (if any).

So where do the pointers to the allocated storage spaces go? If the list is initially empty, insert() feeds the pointer value back to its caller via its out argument, head (which is a separate variable from the like-named ones in other functions). If the list is not initially empty, then the pointer value ends up stored in the next member of one of the nodes.

To free the allocated memory, then, you need to walk the list and free each node, being careful to avoid freeing any given node before reading out its next pointer so as to know what node to free next.

  • Related