【问题标题】:freed BST but still getting memory leak C释放 BST 但仍然出现内存泄漏 C
【发布时间】:2019-03-01 20:17:29
【问题描述】:

我知道有很多人问这个问题,我已经查看了这些帖子上的所有答案,但仍然没有解决我的问题。 我正在尝试在 C 中释放二进制搜索树。我编写了用于释放内存的代码。下面是 Insert、createNode 和 freeNode 的代码:

插入

    Node *insertNode(Node *root, int value) {
    /*
        Insertion of node in Binary Search Tree. The new node must be added in the correct subtree (either left or right).
        If the value is less than the root value then it should be insert in the left subtree. If it's bigger then it should be
        on the right.
    */
    if (root == NULL) {
        //if this is the first node then return its value.
        root = createNode(value);
        return root;
    }
    //on the left subtree
    if (value < root->data) {
        //recurse down the left subtree
        root->left = insertNode(root->left, value);
    } else if (value > root->data) {
        //recurse down the right subtree otherwise.
        root->right = insertNode(root->right, value);
    }

    return root;
}

免费树

void freeSubtree(Node *N) {
   if(N == NULL) {
       return;
   } else{
       freeSubtree(N->right);

       freeSubtree(N->left);
       N->right = NULL;
       N->left = NULL;
   }
       free(N);

}

创建新节点

Node *createNode(int value) {
    //allocate space for the node.
    Node *newNode = (Node *) malloc(sizeof(Node));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;

    return newNode;
}

我不知道为什么我已经释放了所有节点后仍然存在内存泄漏。我看不出我哪里出错了。

任何帮助将不胜感激!

编辑 以下是 valgrind 报告的内存泄漏 Valgrind memory leak error

【问题讨论】:

  • 你怎么知道你有内存泄漏?
  • 那些对我来说看起来不错,使用眼球而不是编译器。可以进行各种小的改进,但我认为没有什么重要的。因此,问题变成了“您如何使用此代码?”请创建一个显示泄漏的 MCVE (minimal reproducible example)。
  • 泄漏来自两个不同的调用链。帮自己一个忙,在你的(所有)构建中包含-g——编译和链接行。然后您将在 Valgrind 输出中获得行号。如果你不使用-g,你就是在浪费 Valgrind。请显示您用于生成泄漏的代码(这是我之前要求的 MCVE)。我们不必猜测您正在执行的操作顺序。
  • 我尝试了这样的main() 函数——使用的数字有几个变体,并且许多运行随机序列——并且从未泄漏任何内存:int main(void) { Node *root = 0; srand(time(0)); for (int i = 0; i &lt; 20; i++) root = insertNode(root, rand() % 53); for (int i = 0; i &lt; 20; i++) root = insertNode(root, (13 * i + 7) % 47); freeSubtree(root); return 0; }——现在至关重要的是,你准确地展示你在做什么。
  • PLo - 确保您使用 -g 编译以生成符号(如果使用 gcc)并将 valgrind 输出作为文本发布在问题底部(正确缩进 4 个空格)。

标签: c memory malloc binary-search-tree free


【解决方案1】:

我根据问题中的内容组装了这段代码。我已经清理了你的三个函数,添加了类型定义、标题、树打印函数和一个main() 程序。我在 Valgrind 下多次运行它,在 main() 程序中使用不同的配置——乘法、加法和模运算中的不同数字,以及构建树的不同序列,以及构建一棵树而不是三棵树,等等。这些都不是导致内存泄漏。

/* SO 5495-1700 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct Node Node;

struct Node
{
    int data;
    Node *left;
    Node *right;
};

static Node *createNode(int value);
static void freeSubtree(Node *node);
static Node *insertNode(Node *root, int value);

Node *insertNode(Node *root, int value)
{
    if (root == NULL)
        root = createNode(value);
    else if (value < root->data)
        root->left = insertNode(root->left, value);
    else if (value > root->data)
        root->right = insertNode(root->right, value);
    return root;
}

void freeSubtree(Node *N)
{
    if (N == NULL)
        return;
    freeSubtree(N->right);
    freeSubtree(N->left);
    N->right = NULL;
    N->left = NULL;
    free(N);
}

Node *createNode(int value)
{
    Node *newNode = (Node *) malloc(sizeof(Node));
    newNode->data = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

static void printValueIndented(int level, int value)
{
    for (int i = 0; i < level; i++)
        fputs("    ", stdout);
    printf("%d\n", value);
}

static void printTree(const char *tag, Node *root, int level)
{
    if (root == NULL)
        return;
    if (level == 0 && tag != NULL)
        printf("%s\n", tag);
    printValueIndented(level, root->data);
    printTree(tag, root->left, level + 1);
    printTree(tag, root->right, level + 1);
}

int main(void)
{
    Node *root = 0;
    srand(time(0));
    for (int i = 0; i < 20; i++)
        root = insertNode(root, i);
    printTree("Sequence", root, 0);
    freeSubtree(root);
    root = 0;
    for (int i = 0; i < 20; i++)
        root = insertNode(root, rand() % 53);
    printTree("Random", root, 0);
    freeSubtree(root);
    root = 0;
    for (int i = 0; i < 20; i++)
        root = insertNode(root, (13 * i + 7) % 47);
    printTree("Computed", root, 0);
    freeSubtree(root);
    return 0;
}

一个示例运行:

Sequence
0
    1
        2
            3
                4
                    5
                        6
                            7
                                8
                                    9
                                        10
                                            11
                                                12
                                                    13
                                                        14
                                                            15
                                                                16
                                                                    17
                                                                        18
                                                                            19
Random
4
    51
        24
            17
                16
                    7
            30
                32
                    31
                    41
                        34
                            36
                                39
                        45
                            43
Computed
7
    4
        1
        6
    20
        12
            9
            17
                14
                19
        33
            25
                22
                30
                    27
            46
                38
                    35
                    43
                        40

因此不清楚您的代码是如何触发内存泄漏的。如果您仍然遇到泄漏,那么您需要显示生成它的确切代码(创建一个 MCVE — Minimal, Complete, Verifiable Example)并在您的(更新的)问题中显示 Valgrind 输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    相关资源
    最近更新 更多