当你有一个指向结构指针的指针时,如何使用realloc?

时间:2016-12-13 20:58:33

标签: c pointers realloc

我有这个结构数组,这个函数接受一个指向数组指针的指针。原始大小为2,所以每当达到大小时,我需要重新分配并加倍大小。当这段代码运行时,我从realloc中得到一个无效的旧大小错误。我做错了什么?

  int PopulateArray(struct Inventory **inv, int *size, FILE *inputFile) {
    int count = 0;
    printf("address: %u\n", inv);
    printf("address: %u\n", **inv);
    int itemNumber;
    int quantity;
    float price;
    int month;
    int year;
    while (fscanf(inputFile, "%i %i %f %i/%i", &itemNumber,
    &quantity, &price, &month, &year) != EOF) {
      (*inv)->itemNumber = itemNumber;
      (*inv)->quantity = quantity;
      (*inv)->price = price;
      (*inv)->expDate.month = month;
      (*inv)->expDate.year = year;
      printf("count: %i  size: %i\n", count, *size);

      if (count == *size - 1) {
        inv = realloc(inv, (*size * 2 * sizeof(struct Inventory)));
        *size *= 2;
      }
      inv++;
      count++;
    }
    return count;
  }

3 个答案:

答案 0 :(得分:4)

在你的函数中,inv(推测)是指针变量的地址。它是您要传递给realloc的变量的值。

*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));

出于同样的原因,递增inv本身不会达到您的预期。

因为您需要使用realloc,所以您应该使用count来引用该数组。

while (fscanf(inputFile, "%i %i %f %i/%i", &itemNumber,
    &quantity, &price, &month, &year) != EOF) {
  (*inv)[count].itemNumber = itemNumber;
  (*inv)[count].quantity = quantity;
  (*inv)[count].price = price;
  (*inv)[count].expDate.month = month;
  (*inv)[count].expDate.year = year;
  printf("count: %i  size: %i\n", count, *size);

  if (count == *size - 1) {
    *inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
    if (*inv == NULL) {
        perror("realloc failed");
        exit(1);
    }
    *size *= 2;
  }
  count++;
}

答案 1 :(得分:3)

出现问题是因为您正在修改invinv++;)。

如果传递的指针是有效的分配指针,而不是指定区域内的指针,则只能realloc数据。

因此,您必须存储inv数据,以便使用realloc。当前元素上的指针必须是不同的变量。

在分配回realloc之前检查NULL是否未返回inv,否则您将丢失原始指针。

这几乎让我错过了最大的错误(1个错误隐藏了另一个错误,经典):你传递的是struct Inventory **类型,所以你可以修改指针,但是你要修改双指针。< / p>

您应该在指向的值上执行realloc,而不是在指针的地址上执行:

*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));

答案 2 :(得分:0)

当您从inv更新realloc()时,您的inv现在指向新调整大小的数组的 start 。那么,你的代码

  if (count == *size - 1) {
    inv = realloc(inv, (*size * 2 * sizeof(struct Inventory*)));
    *size *= 2;
  }
  inv++;

最后inv++会使inv有效地指向inv[1],而不是您可能想要指向的inv[count]

我在下面添加,因为错误的答案正在被投票

的建议
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));

不正确。

您尝试做的是动态地加倍指针数组。因此,传递给realloc的正确指针类型为struct Inventory **

(您可能已经按pptr = malloc(sizeof(struct Inventory*) * INIT_SIZE)创建了初始表格,因此此处inv的{​​{1}}类型正确无误

话虽如此,在您的函数中执行realloc之后,调用 this 函数的代码使用的原始realloc指针不再有效,所以返回此函数,您将丢失指向已调整大小的数组的指针。要处理这个问题,您必须将新的inv指针值返回给调用函数。

额外编辑:

并且不要忘记为实际的inv项目分配内存:

struct Inventory

在循环开始时。