我将这个结构用于我的树:
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;
}
哪个没有给出分段错误,但是当我打印数组时,有空位置。 我需要一些关于我错在哪里的提示。可能是索引和递归调用的问题,但我无法弄清楚。
答案 0 :(得分:3)
查看这两个运算符的precedence
*index++
++
增量的优先级高于*
dereference对吗?
因此,如果您首先通过sizeof(int)
移动到内存中,那么您在分配的内存中不再存在,并且解除引用会导致UB。
如果您不确定优先级,最好使用括号()
。
(*index)++ // This is right
答案 1 :(得分:0)
菲利普已经指出了你的第一个功能的问题。
第二个功能的问题是它只在从左侧分支填充时才起作用。完成并复制当前产品后,数组中有一些元素,但从右分支复制将再次从索引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;
}