[英]How do you use realloc when you have a pointer to a pointer of a struct?
I have this array of structs and this function takes a pointer to the pointer of the array. 我有这个结构数组,这个函数接受一个指向数组指针的指针。 The original size is 2, so whenever it reaches the size, I need to realloc and double the size.
原始大小为2,所以每当达到大小时,我需要重新分配并加倍大小。 When this code runs, I get an invalid old size error from the realloc.
当这段代码运行时,我从realloc中得到一个无效的旧大小错误。 What am I doing wrong?
我究竟做错了什么?
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;
}
In your function, inv
is (presumably) the address of a pointer variable. 在你的函数中,
inv
(推测)是指针变量的地址。 Its the value of that variable you want to pass to realloc
. 它是您要传递给
realloc
变量的值。
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
For the same reason, incrementing inv
itself won't do what you expect. 出于同样的原因,递增
inv
本身不会达到预期效果。
Because you need to use realloc
, you should use count
to reference the array. 因为您需要使用
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++;
}
The problem occurs because you're modifying inv
( inv++;
). 出现此问题是因为您正在修改
inv
( inv++;
)。
You can only realloc
data if the passed pointer is a valid allocated pointer, not a pointer within the allocated zone. 您只能
realloc
如果传递的指针是有效分配的指针,而不是分配给区域内的数据指针,
So you have to store your inv
data so you can use realloc
. 因此,您必须存储您的
inv
数据,以便您可以使用realloc
。 Pointer on the current element must be a different variable. 当前元素上的指针必须是不同的变量。
And check that realloc
doesn't return NULL
before assigning back to inv
or you'll lose your original pointer. 并且在分配回
inv
之前检查realloc
是否返回NULL
,否则您将丢失原始指针。
That almost made me miss the biggest mistake (1 mistake hiding the other, classical): you're passing a struct Inventory **
type so you can modify the pointer, but you're modifying the double pointer instead. 这几乎让我错过了最大的错误(1个错误隐藏了另一个错误,经典):你传递的是一个
struct Inventory **
类型,所以你可以修改指针,但你要修改双指针。
You should perform your realloc on the pointed value, not on the address of the pointer: 您应该在指向的值上执行realloc,而不是在指针的地址上执行:
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
When you update inv
from realloc()
, your inv
now points to the start of the newly resized array. 当您从
realloc()
更新inv
,您的inv
现在指向新调整大小的数组的开头 。 So, your code 所以,你的代码
if (count == *size - 1) {
inv = realloc(inv, (*size * 2 * sizeof(struct Inventory*)));
*size *= 2;
}
inv++;
the last inv++
will make inv
point effectively to inv[1]
, not the inv[count]
which you would probably wanted to point to. 最后一个
inv++
会使inv
点有效地成为inv[1]
,而不是你可能想要指向的inv[count]
。
I am adding below because incorrect answers are being upvoted 我在下面添加,因为错误的答案正在被投票
The suggestion of 的建议
*inv = realloc(*inv, (*size * 2 * sizeof(struct Inventory)));
is not correct. 是不正确的。
What you are attempting to do is doubling the array of pointers dynamically. 你试图做的是动态地加倍指针数组。 So the correct pointer type to pass to
realloc
here is struct Inventory **
. 因此,传递给
realloc
的正确指针类型是struct Inventory **
。
(You probably created initial table by pptr = malloc(sizeof(struct Inventory*) * INIT_SIZE)
, so inv
is correct type for realloc
here) (你可能通过
pptr = malloc(sizeof(struct Inventory*) * INIT_SIZE)
创建了初始表,所以inv
是realloc
正确类型)
Having said that, after you performing the realloc
in your function, the original inv
pointer used by the code that called this function is no longer valid, so upon returning this function, you lose your pointer to the resized array. 话虽如此,在您的函数中执行
realloc
之后,调用此函数的代码使用的原始inv
指针不再有效,因此在返回此函数时,您将丢失指向调整大小的数组的指针。 To deal with this, you have to return the new inv
pointer value to the calling function. 要处理这个问题,您必须将新的
inv
指针值返回给调用函数。
additional edit: 额外编辑:
And don't forget to allocate memory for the actual struct Inventory
item: 并且不要忘记为实际的
struct Inventory
项目分配内存:
inv[count] = malloc(sizeof(struct Inventory));
at the start of the loop. 在循环的开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.