简体   繁体   中英

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

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM