【问题标题】:Segmentation fault copying tree nodes into array分段错误将树节点复制到数组中
【发布时间】:2017-08-24 12:00:50
【问题描述】:

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

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

这不会给出分段错误,但是当我打印数组时有空位置。 我需要一些关于我错在哪里的提示。可能是索引和递归调用有问题,但我想不通。

【问题讨论】:

  • 使用调试器似乎是了解您的问题的最佳方式。缺少对 products_a 的溢出测试。
  • 我认为 *index++ 没有达到您的预期。

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


【解决方案1】:

看看这两个运算符的precedence

*index++

++ 增量的优先级高于 * 取消引用,对吗?

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

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

(*index)++ // This is right

【讨论】:

    【解决方案2】:

    Filip 已经指出了您的第一个函数的问题。

    您的第二个函数的问题是它仅在从左分支填充时才有效。完成此操作并复制当前产品后,数组中有一些元素,但从右分支复制将再次从索引 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多