为什么我的递归使用指针在C崩溃?

4nkexdtk  于 2023-02-03  发布在  其他
关注(0)|答案(2)|浏览(87)

我目前正在学习计算机科学,我们开始使用指针。我有一种感觉,我开始理解指针,但我遇到了一个问题,不能找出哪里出错了。
我们这样定义一棵树:

typedef struct node *tree;
struct node {int key; tree left, right;};

现在我们应该编写一个函数,用三个参数创建节点,即节点的键、左边的节点和应该在节点“下面”的右边的节点。我是这样做的,看起来很有效:

tree createNode(int n, tree l, tree r){
    tree node = (tree) malloc(sizeof(tree));
    node->key = n;
    node->left = l;
    node->right = r;
    return node;
}

最后,我们应该写一个函数,乘以所有的叶子树,我认为最简单的方法是从根开始,通过递归搜索叶子,然后乘以它们.但当我调用函数的程序似乎崩溃在函数的中间.我的函数看起来像这样:

int leafprod(tree t){
    printf("%d\n", t->key);

    if (t->left == NULL){
        if (t->right == NULL){
            printf("$1\n\n");
            return t->key;
        }
        printf("$2\n\n");
        return leafprod(t->right);
    }
    if (t->right == NULL){
        printf("$3\n\n");
        return leafprod(t->left);
    }
    printf("$4\n\n");
    return leafprod(t->left) * leafprod(t->right);
}

我调用main函数中的函数,如下所示:

int main(){
    tree a = createNode(1, NULL, NULL);
    tree b = createNode(2, NULL, NULL);
    tree c = createNode(3, a, NULL);
    tree d = createNode(4, b, c);

    int n = leafprod(d);

    printf("end: %d", n);

    free(a);
    free(b);
    free(c);
    free(d);

    return 0;
}

我使用print语句跟踪程序并试图定位错误,但在大多数情况下它什么也不打印,有时它会打印:

4
$4

2
$2

而且程序只运行了两次整个代码。我相信也许我用错了malloc函数,但我不能说。

wvmv3b1j

wvmv3b1j1#

问题出在这一行:

tree node = (tree) malloc(sizeof(tree));

tree是指向struct node的指针的类型定义,因此sizeof(tree)只是指针的大小。
您应该改为使用以下方法之一:

tree node = malloc(sizeof(*l));

或者:

tree node = malloc(sizeof(*r));

*l*r的类型为struct node(不是指针),这是您尝试创建的元素。
@IanAbbott评论的另一个选项是:

tree node = malloc(sizeof(*node));

注意这里的node是变量名,而不是类型(在C语言中,类型需要以struct为前缀,即struct node),这种方法的优点是语句不依赖于其他变量。

    • 边注:**

1.您不应该强制转换malloc的结果。请参见此处:Do I cast the result of malloc?.
1.用typedefs隐藏指针类型不是一个好的做法,你可以考虑避免它(如果你想节省在任何地方使用struct关键字的需要,你可以使用typedef struct node Node)。

xzabzqsa

xzabzqsa2#

不要使用typedef来隐藏指针类型。
对于typedef struct node *tree;,您不知道代码中的tree是什么,因此会产生混淆。
通常在这里tree node = (tree) malloc(sizeof(tree))你做错了,主要原因可能是因为你不知道tree实际上是什么。

...
struct node 
{
  int key;
  struct node* left;
  struct node *right;
};

struct node* createNode(int n, struct node*l, struct node*r) {

  struct node* node = malloc(sizeof(*node));   // don't use the cast, it's useless
   ...
}

int leafprod(struct node* t) {
...

相关问题