简体   繁体   English

在 C 中的 function 中使用 free() 分配和释放 memory

[英]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.我只是无法弄清楚如何释放我在 function 中分配的 memory。

#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,如果我使用gcc main.c -fsanitize=address -o main &&./main运行它,那么它会警告我 memory 泄漏如下所示,

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.我知道我在arrayToLL(int *arr, int size)中分配的头指针可以由主function的free(head)释放。 But what about the *temp and *ptr inside insert(node_t** head, int data) .但是insert(node_t** head, int data)里面的*temp*ptr呢? And I am guessing these not released allocated memory is causing the memory leaks.而且我猜这些未发布的分配 memory 导致 memory 泄漏。

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?我的问题是如何释放我在 void function 内分配的指针 memory 或至少如何避免那些 memory 泄漏?

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.我知道我在arrayToLL(int *arr, int size)中分配的头指针可以由主function的free(head)释放。

In your program, all dynamic memory allocation occurs in arrayToLL() , but none occurs directly in that function.在您的程序中,所有动态 memory 分配都发生在arrayToLL()中,但没有直接发生在 function 中。 Only function insert() calls malloc() directly.只有 function insert() malloc()

But what about the *temp and *ptr inside insert(node_t** head, int data) .但是insert(node_t** head, int data)里面的*temp*ptr呢?

It is not about the variables that store pointers to the allocated space, as you should already know based on your remarks about head .这与存储指向已分配空间的指针的变量无关,因为您应该根据您对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?那么指向已分配存储空间 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).如果列表最初为空,则insert()通过其 out 参数将指针值反馈给其调用者, head (与其他函数中的同名变量不同)。 If the list is not initially empty, then the pointer value ends up stored in the next member of one of the nodes.如果列表最初不是空的,则指针值最终存储在其中一个节点的next成员中。

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.为了释放分配的 memory,然后,您需要遍历列表并释放每个节点,小心避免在读取其next指针之前释放任何给定节点,以便知道下一个要释放的节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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