当你有一个指向结构指针的指针时,你如何使用 realloc?
How do you use realloc when you have a pointer to a pointer of a struct?
我有这个结构数组,这个函数接受一个指向数组指针的指针。原来的大小是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;
}
在您的函数中,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++;
}
出现问题是因为您正在修改 inv
(inv++;
)。
如果传递的指针是有效的分配指针,而不是分配区域内的指针,则只能realloc
数据。
因此您必须存储 inv
数据以便可以使用 realloc
。当前元素上的指针必须是不同的变量。
并在分配回 inv
之前检查 realloc
是否 return NULL
否则您将丢失原始指针。
这几乎让我错过了最大的错误(一个错误隐藏了另一个,经典的):你传递了一个 struct Inventory **
类型,所以你可以修改指针,但你修改的是双指针.
您应该对指向的值而不是指针的地址执行重新分配:
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
当您从 realloc()
更新 inv
时,您的 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)
创建了初始 table,因此 inv
是此处 realloc
的正确类型)
话虽如此,在您的函数中执行 realloc
之后,调用 this 函数的代码使用的原始 inv
指针是没有的不再有效,所以在 returning 这个函数时,你失去了指向调整大小的数组的指针。要处理这个问题,您必须 return 新的 inv
指针值指向调用函数。
补充编辑:
并且不要忘记为实际的 struct Inventory
项分配内存:
inv[count] = malloc(sizeof(struct Inventory));
在循环开始时。
我有这个结构数组,这个函数接受一个指向数组指针的指针。原来的大小是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;
}
在您的函数中,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++;
}
出现问题是因为您正在修改 inv
(inv++;
)。
如果传递的指针是有效的分配指针,而不是分配区域内的指针,则只能realloc
数据。
因此您必须存储 inv
数据以便可以使用 realloc
。当前元素上的指针必须是不同的变量。
并在分配回 inv
之前检查 realloc
是否 return NULL
否则您将丢失原始指针。
这几乎让我错过了最大的错误(一个错误隐藏了另一个,经典的):你传递了一个 struct Inventory **
类型,所以你可以修改指针,但你修改的是双指针.
您应该对指向的值而不是指针的地址执行重新分配:
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
当您从 realloc()
更新 inv
时,您的 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)
创建了初始 table,因此 inv
是此处 realloc
的正确类型)
话虽如此,在您的函数中执行 realloc
之后,调用 this 函数的代码使用的原始 inv
指针是没有的不再有效,所以在 returning 这个函数时,你失去了指向调整大小的数组的指针。要处理这个问题,您必须 return 新的 inv
指针值指向调用函数。
补充编辑:
并且不要忘记为实际的 struct Inventory
项分配内存:
inv[count] = malloc(sizeof(struct Inventory));
在循环开始时。