分段故障将树节点复制到数组中

时间:2017-08-24 12:00:51

标签: c arrays pointers segmentation-fault binary-tree

我将这个结构用于我的树:

  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;
 }

哪个没有给出分段错误,但是当我打印数组时,有空位置。 我需要一些关于我错在哪里的提示。可能是索引和递归调用的问题,但我无法弄清楚。

2 个答案:

答案 0 :(得分:3)

查看这两个运算符的precedence

*index++

++增量的优先级高于* dereference对吗?

因此,如果您首先通过sizeof(int)移动到内存中,那么您在分配的内存中不再存在,并且解除引用会导致UB。

如果您不确定优先级,最好使用括号()

(*index)++ // This is right

答案 1 :(得分:0)

菲利普已经指出了你的第一个功能的问题。

第二个功能的问题是它只在从左侧分支填充时才起作用。完成并复制当前产品后,数组中有一些元素,但从右分支复制将再次从索引0开始,因此它将覆盖现有数据并在最后保留数据未初始化。

您可以通过将当前索引i传递给您的函数来解决此问题,但我发现i = func(..., i);语法有点多余。

在C中,您可以使用arrayi从元素&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;
}