调整函数内的结构数组的大小

时间:2016-08-24 18:39:09

标签: c arrays dynamic struct

我想动态地将新元素添加到结构数组中。我添加了一个最小的segfaults示例。我想我必须将一个指针struct data **arr传递给函数来重新分配并正确添加新元素,但我还没有能够正确地完成它。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

struct data {
    char s[10];
    int arr[10];
};

void add_one_element(struct data *arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  arr = realloc(arr, *num_elements * sizeof(struct data));

  strcpy(arr[*num_elements-1].s, "ABC");
  for(int i = 0; i < 10; i++)
    arr[*num_elements-1].arr[i] = i;
}


int main()
{
   struct data *arr = NULL;
   int num_elements = 0;
   add_one_element(arr, &num_elements);

   printf("arr.s = %s\n", arr[num_elements-1].s);
   for(int i = 0; i < 10; i++)
        printf("arr[%d].arr[%d] = %d\n", num_elements-1, i, arr[num_elements-1].arr[i]);

   free(arr);
   return 0;
}

编辑1:试图纠正问题。这次我得test(91537,0x7fff79532000) malloc: *** error for object 0x7fff5f5c0ad0: pointer being realloc'd was not allocated。这表明重新分配失败了。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

struct data {
    char s[10];
    int arr[10];
};

void add_one_element(struct data **arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  arr = realloc(arr, *num_elements * sizeof(struct data));

  strcpy(arr[*num_elements-1]->s, "ABC");
  for(int i = 0; i < 10; i++)
    arr[*num_elements]->arr[i] = i;
}


int main()
{
   struct data *arr = NULL;
   int num_elements = 0;
   add_one_element(&arr, &num_elements);
   printf("arr.s => %s\n", arr[num_elements-1].s);
   for(int i = 0; i < 10; i++)
        printf("arr[%d].arr[%d] = %d\n", num_elements-1, i, arr[num_elements-1].arr[i]);
   return 0;
}

2 个答案:

答案 0 :(得分:3)

你是正确的,你需要将struct data **传递给你的函数。你可以这样做:

void add_one_element(struct data **arr, int *num_elements)
{
  /*increment counter*/
  *num_elements +=1;
  *arr = realloc(*arr, *num_elements * sizeof(struct data));

  strcpy((*arr)[*num_elements-1].s, "ABC");
  for(int i = 0; i < 10; i++)
    (*arr)[*num_elements-1].arr[i] = i;
}

因此,您在此函数中引用arr的任何地方都将更改为*arr。请注意,此表达式带有括号,以便访问数组元素。

然后你调用这样的函数:

add_one_element(&arr, &num_elements);

答案 1 :(得分:2)

由于C经过值传递,因此无法在没有引用的情况下更改调用者的变量值。在C中,这是通过取消引用指向函数需要更改的变量的指针来完成的。因此,您需要将指针传递给指针变量。

(在您编辑的更改中,您没有取消引用指针变量。)

realloc可能返回NULL,在这种情况下,原始指针尚未被释放。因此,您需要在单独的变量中捕获并测试结果或realloc

void add_one_element(struct data **arr, int *num_elements)
{
  struct data *tmp;
  int tmp_num = *num_elements + 1;

  /*increment counter*/
  tmp = realloc(*arr, tmp_num * sizeof(struct data));
  if (tmp == NULL) {
      /* XXX: handle the error */
      return;
  }

  strcpy(tmp[tmp_num-1].s, "ABC");
  for(int i = 0; i < 10; i++)
    tmp[tmp_num-1].arr[i] = i;

  *arr = tmp;
  *num_elements = tmp_num;
}