C语言 将树节点复制到数组中的分段故障

ttygqcqt  于 2023-06-21  发布在  其他
关注(0)|答案(2)|浏览(89)

我用这个结构来构建我的树:

typedef struct product{
      char name[50];
      char id[5];
      double price;
      int amount;
      struct product *left_p, *right_p;
  }product_t;

因此,我必须将树转换为数组。我为树维度写了这个:

int tree_dim(product_t *node_p){
    int i = 1 ;
    if (node_p == NULL)
        i = 0;
    else{
        i += tree_dim(node_p->left_p);
        i += tree_dim(node_p->right_p);
    }
    return i;
}

我的树是通过从一个txt文件中阅读记录来填充的。记录数为21,tree_dim返回的值正确。该值存储在arr_dim中。
然后创建一个product_t *products_a;,它将作为“数组”,并使用products_a = malloc (arr_dim*sizeof (product_t));将其分配到内存中
现在,这是用树节点填充数组的函数:

void fill_array(int *index, product_t *node_p, product_t *products_a){

    if (node_p != NULL){
        fill_array(index, node_p->left_p, products_a);
        products_a[*index++] = *node_p;
        fill_array(index, node_p->right_p, products_a);
    
    }
}

但是它给了我分割错误,所以我也尝试了这个第二个解决方案:

int fill_array(product_t *node_p, product_t *products_a){

    int i = 1 ;
    if (node_p == NULL){
        i=0;
    }
    else
    {
        i += fill_array(node_p->left_p, products_a);
        products_a[i-1] = *node_p;
        i += fill_array(node_p->right_p, products_a);
    
    }
    return i;
 }

这并没有给予分段错误,但当我打印数组时,有空位置。我需要一些关于我错在哪里的提示。也许是索引和递归调用的问题,但我无法解决。

hi3rlvi2

hi3rlvi21#

查看这两个运算符的precedence

*index++

++增量的优先级高于*解引用的优先级,对吗?
因此,如果你首先在内存中移动sizeof(int),那么你就不在你分配的内存中,解引用将导致UB。
如果你不确定优先级,最好使用方括号()

(*index)++ // This is right
a14dhokn

a14dhokn2#

菲利普已经指出了你第一个函数的问题。
第二个函数的问题是,它只在从左分支填充时有效。在你完成这一步并复制当前产品之后,数组中有一些元素,但是从右分支复制将再次从索引0开始,因此它将覆盖现有数据并使末尾的数据未初始化。
您可以通过将当前索引i传递给您的函数来解决这个问题,但我发现i = func(..., i);语法有点多余。
在C中,你可以传入一个array的子数组,从元素i开始,带有&array[i]或仅为array + i。(请记住,函数调用中的数组“衰减”为指向第一个元素&array[0]的指针。
这样就行了

int fill_array(product_t *node_p, product_t *products_a)
{        
    int i = 0;

    if (node_p == NULL) return 0;

    i += fill_array(node_p->left_p, products_a);
    products_a[i++] = *node_p;
    i += fill_array(node_p->right_p, &products_a[i]);

    return i;
}

相关问题