C malloc堆栈与堆问题

时间:2015-09-22 02:27:06

标签: c binary-search-tree heap-memory stack-memory

我在C中实现了二叉搜索树的插入功能,我遇到了malloc的问题。

首先,我有一个树和节点结构

typedef struct Node {
    double value;

    struct Node *parent;
    struct Node *right_child;
    struct Node *left_child;
} Node;

typedef struct Tree {
    struct Node *root;
} Tree;

这是我的插入函数,用于在树中插入一个值。

void insert(Tree *t, double v) {

    Node *n = malloc(sizeof(Node));
    n->left_child = malloc(sizeof(Node));
    n->right_child = malloc(sizeof(Node));
    n->parent = malloc(sizeof(Node));
    n->value=v;

    Node *x = t->root, *y = NULL;

    //follow tree down until we reach a leaf of the tree
    while (x) {

        //save last non-NULL value. We will insert node n as a child to this leaf.
        y = x;

        if (n->value < x->value) {
            x = x->left_child;
        } else {
            x = x->right_child;
        }
    }

    //The parent of the node to insert is the leaf we reached
    n->parent = y;

    //If n is greater than y then it is its right child and vice-versa.
    if (n->value > y->value) {
        y->right_child = n;
    } else {
        y->left_child = n;
    }

}

我的主要方法

int main(void) {

    Node n1;

    n1.value = 4;
    n1.parent = NULL;
    n1.left_child = NULL;
    n1.right_child = NULL;

    Tree t;

    t.root = &n1;

    insert(&t,2.0);

    printf("In order traversal\n");
    inOrderTraversalNode(t.root);

    return EXIT_SUCCESS;
}

当我打印有序的几个代码时,我得到了未定义的行为(例如:26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.000000),而不是正确的遍历。

我很确定问题是Node方法中的insert创建。我假设问题是堆栈上存在新节点,然后在insert函数退出时被销毁 - 这是导致遍历期间未定义行为的原因。但是,我认为malloc将变量存储在堆上并使其全局可用。或者节点可能在堆上,但指针在堆栈上?有人能告诉我我在哪里错了吗?

2 个答案:

答案 0 :(得分:1)

通过malloc分配的内存中的初始内容未定义。

首先,删除导致内存泄漏的n->parent = malloc(sizeof(Node));

其次,改变

  n->left_child = malloc(sizeof(Node));
  n->right_child = malloc(sizeof(Node));

  n->left_child = NULL;
  n->right_child = NULL;

以便程序可以正确识别叶子。

答案 1 :(得分:1)

尝试使用calloc代替malloc。问题是malloc没有将值初始化为零,只有 分配空间。 calloc将您要求的空间归零。所以,当你找到一个无效的指针但是不是NULL时,你偶尔会跳到一个随机的内存部分。

malloc和朋友肯定在堆上分配,你有正确的想法;他们返回的是一个指针到内存中至少是你所请求的大小的空间,它绝对可以安全地读取和写入。但是,由于在使用malloc时该值未被清零,因此您无法保证结构中存储的指针实际上位于有效位置。

编辑:另外,其他海报是正确的:你正在做的事情确实存在内存泄漏。没听清楚。