简体   繁体   English

何时释放 c 中分配的 memory?

[英]when to free an allocated memory in c?

I tried using valgrind to run the following code.我尝试使用 valgrind 运行以下代码。 Some heap leak is observed in the functions below.在下面的函数中观察到一些堆泄漏。 My question is where is the correct position to free the memory being allocated?我的问题是正确的 position 在哪里释放正在分配的 memory? And also in terms of recursion such as the trav = trav -> right, do i need to free it up also?而且在递归方面,例如 trav = trav -> 对,我还需要释放它吗?

TTreeNode *makeNewNode(char *name, char *phoneNum)
{
   
    TTreeNode *newNode = (TTreeNode *)malloc(sizeof(TTreeNode));
    name = (char *)malloc(strlen(name)+1);
    newNode->name = name;
//phone num is a array pointer, do i need to alloc memory to it too?
    strcpy(newNode->phoneNum, phoneNum);
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

void addPerson(char *name, char *phoneNum) {
    if(findPerson(name) == NULL) 
    {
        TTreeNode *node = makeNewNode(name, phoneNum);
        addNode(&_root, node);
    }
    else
        printf("%s is already in phonebook.\n", name);
}

void addNode(TTreeNode **root, TTreeNode *node)
{
    // printf("%s\n", *root);
    if (*root == NULL)
    {
        *root = makeNewNode(node->name, node->phoneNum);
        return;
    }

    // printf("%s\n", *root);

    TTreeNode *trav;
    trav = (TTreeNode *)malloc(sizeof(TTreeNode));
    trav = *root;
    while (trav != NULL)
    { 
       int cmp = strcmp(trav->name, node->name);
        if (cmp < 0)
        {
            if (trav->right == NULL)
            {
                trav->right = node;
                
                break;
            }
            else
               {trav = trav->right;
                }
        }

        else
        {
            if (trav->left == NULL)
            {
                trav->left = node;
                break;
                
            }
            else
                {trav = trav->left;
                }
        }
    }
  
}

this is how i free the memory:这就是我释放 memory 的方式:

void freenode(TTreeNode *node)
{
    // Frees the memory used by node.
    if (node != NULL)
    {
        free(node);
        
    }
    node = NULL;
}

the main function:主要 function:

int main() {
    TData data[ITEMS] = {{"Fred Astaire", "95551234"}, {"Jean Valjean",
    "95558764"}, {"Gal Gadoti", "95551123"}, {"Aiken Dueet", "95558876"},
    {"Victor Hugo", "95524601"}};

    int i;

    for(i = 0; i<ITEMS; i++){
        printf("Adding %s, phone number %s\n", data[i].name, data[i].tel);
        addPerson(data[i].name, data[i].tel);
    }

    printf("\nNow retrieiving stored data.\n");
    char *result;

    for(i=0; i<ITEMS; i++) {
        printResult(data[i].name);
    }

printf("\nPrinting entire phonebook.\n");
    print_phonebook();

    printf("\nDeleting Aiken Dueet.\n");
    delPerson("Aiken Dueet");
    print_phonebook();

   
}

In practice you need to free before reusing a pointer for something else.在实践中,您需要在将指针重用于其他内容之前释放。 Not doing so is what typically cause memory leaks.不这样做通常会导致 memory 泄漏。

You don't need to free before exiting.您无需在退出前释放。 Usually, the operating system will take care of that for you.通常,操作系统会为您处理这些问题。 There are rare exceptions though.不过也有极少数例外。

Other than that, a rule of thumb is to free the memory when you are done using it.除此之外,经验法则是在使用完 memory 后释放它。

Your cleanup function is not good.你的清理 function 不好。 Here is a proper one:这是一个合适的:

void freenode(TTreeNode *node)
{
    if (node != NULL)
    {
        freenode(node->left);
        freenode(node->right);

        free(node->phoneNum);
        free(node->name);
    }

    free(node);
}

Oh, and don't cast malloc.哦,不要投 malloc。

Do I cast the result of malloc?我要转换 malloc 的结果吗? And do I pass the size of the type or the object?我是否传递类型或 object 的大小?

You don't have to free memory when iterating through linked list.遍历链表时,您不必释放 memory。 If you want to free each node after you don't need to use the linked list any more, you can write a function which takes the linked list as a parameter and iterates through it by freeing each node until it reaches to NULL.如果您想在不再需要使用链表后释放每个节点,您可以编写一个 function,它将链表作为参数并通过释放每个节点来迭代它,直到它到达 NULL。

It is really not necessary to free the memory you used especially through iterations in a list, whether it is linked or not.确实没有必要释放您使用的 memory,尤其是通过列表中的迭代,无论它是否已链接。 I understand you want to free every node after the list is useless for you, so you have to write a function that frees every node until node==NULL .我知道您想在列表对您无用之后释放每个节点,因此您必须编写一个 function 释放每个节点直到node==NULL

This answered question might be helpful for the function you need to create.这个已回答的问题可能对您需要创建的 function 有所帮助。

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

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