如何在函数中使用 realloc 创建动态结构数组
How to create dynamic array of structs using realloc in function
我正在尝试使用 realloc 创建结构的动态数组(在本例中为图片)。我想在函数中这样做,但是有一个问题:main 中的变量不会被这个函数改变。指针一定有问题,但我找不到它。
PS: 函数 UploadFile 工作正常。
有一个函数:
int AddPicture(struct Picture ***tab, int *PicCounter)
{
struct Picture *temp;
struct Picture pic;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) *sizeof(*temp));
if (temp != NULL)
{
UploadFile(&pic);
**tab = temp;
(*tab)[*PicCounter-1]->name = pic.name;
(*tab)[*PicCounter-1]->type[0] = pic.type[0];
(*tab)[*PicCounter-1]->type[1] = pic.type[1];
(*tab)[*PicCounter-1]->width = pic.width;
(*tab)[*PicCounter-1]->height = pic.height;
(*tab)[*PicCounter-1]->scale = pic.scale;
(*tab)[*PicCounter-1]->table = pic.table;
}
else {
printf("Memory reallocation error");
free(temp);
return 1;
}
return 0;
}
我是这样称呼它的:
struct Picture *tabofpics;
int piccounter = 0;
tabofpics = malloc(1 * sizeof(*tabofpics));
AddPicture(&tabofpics,&piccounter);
感谢您的帮助。
编辑:
我试过 **tab 而不是 ***tab 并且 main 中的值是正确的,但它的行为就像内存没有正确重新分配,即使 realloc 没有 return NULL。
int AddPicture(struct Picture **tab, int *PicCounter)
{
struct Picture *temp;
struct Picture pic;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) * sizeof(*temp));
if (temp != NULL)
{
UploadFile(&pic);
*tab = temp;
tab[*PicCounter - 1]->name = pic.name;
tab[*PicCounter - 1]->type[0] = pic.type[0];
tab[*PicCounter - 1]->type[1] = pic.type[1];
tab[*PicCounter - 1]->width = pic.width;
tab[*PicCounter - 1]->height = pic.height;
tab[*PicCounter - 1]->scale = pic.scale;
tab[*PicCounter - 1]->table = pic.table;
}
else {
printf("Memory reallocation error");
free(*tab);
return 1;
}
return 0;
}
这个想法是在程序中放多少张图片就放多少张,对其进行一些操作然后离开。必须有添加和删除图片的功能,只要用户想要,但是当我第二次在参数中使用 **tab 调用函数时,我得到了访问冲突位置,所以正如我之前提到的,realloc 一定不能正常工作。
在我看来,您需要改进代码的逻辑,例如
- 还不递增
PicCounter
- 您的指针间接级别不匹配,在调用函数中您有
struct Picture *
并且您将其作为 struct Picture **
传递给采用 struct Picture ***
的函数。您应该对此进行推理,以及您真正想要的是什么。看来你想要一个 struct Picture *
. 的数组
风格,
- 不要使用
PicCounter
作为变量,使用 number_of_pictures
或更合适的东西。
- 不要写
1 * sizeof(...)
它太露骨了,你不需要那么多。
工具,
- 启用编译器警告以发现您在没有注意到的情况下犯下的简单错误,或者那些概念上的错误,例如代码中指针的间接寻址不匹配。
也就是说,我想你可能想写这个
int
AddPicture(struct Picture ***tab, int *counter)
{
struct Picture **array;
array = realloc(*tab, (*counter + 1) * sizeof(*array));
if (array != NULL)
{
struct Picture *current;
// We will avoid using the `tab' variable because it's
// confusing, the only reason why it's a *** pointer is
// to do this here, and below where we set it to `NULL'
*tab = array;
// We also need to allocate space for a new image to store
// the results in.
current = malloc(sizeof(*current));
if (current == NULL)
goto error;
// This is a guess, but isn't the code just initializing
// the `pic' that you allocated on the stack?
//
// Well, the following is the same.
//
// Oh, and should we check for errors here?
UploadFile(current);
// Now we can increase counterand update our array
array[(*counter)++] = current;
// We have succeded, so return 0
return 0;
}
error:
printf("Memory reallocation error");
// Release memory allocated so far
free(*tab);
// Prevent dangling pointer
*counter = 0;
*tab = NULL;
// A non zero value means, an error
return 1;
}
调用函数应该是这样的
struct Picture **tabofpics;
int counter = 0;
// `realloc' will take car of the allocation
tabofpics = NULL;
if (AddPicture(&tabofpics, &picounter) == 0)
// Everything ok, picture added
else
// Error
请小心 ***
指针,它们会引起很多混乱。我要考虑四五次
(*tab)[*counter] = current;
在我看到它是正确的之前。所以我选择更改它,如您在代码中看到的那样。
您的代码应尽可能具有描述性,使用 ***
指针会导致错误的方向。
您的代码中的以下两个摘录或许可以最好地概括核心问题:
temp = realloc(*tab, (*PicCounter) *sizeof(*temp));
[...]
**tab = temp;
您正在重新分配由 *tab
的值指向的 space,但成功后,您将指向新 space 的指针存储在 **tab
中,这是一个不同的位置。不管哪一个是指针的正确位置,组合肯定是错误的。
然而,事实上,考虑到您调用函数的方式...
struct Picture *tabofpics;
[...]
AddPicture(&tabofpics,&piccounter);
...实参的类型是struct Picture **
。这适合您的目的,因此您应该调整函数定义以匹配:
int AddPicture(struct Picture **tab, int *PicCounter)
。此外,您应该确保头文件中存在匹配的函数声明,该头文件 #include
d 进入包含 AddPicture
定义的源文件以及包含对该函数的调用的每个源文件。再加上确保出现编译器警告,编译器应该能够帮助您诊断此函数的定义和使用之间的不匹配。
完成后,函数 AddPicture()
中的表达式 *tab
将引用表达式 tabofpics
(无 *
)在 main()
。这似乎与您实际使用它的方式一致,但我在开头描述的不匹配除外。
可以对您的代码提出其他合理的批评,但@Iharob 已经在他的回答中很好地解决了这些问题。
根据@Iharob 和@John 的回答,我能够编写一个工作函数:
int AddPicture(struct Picture **tab, int *PicCounter)
{
struct Picture *temp;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) * sizeof(*temp));
if (temp != NULL)
{
struct Picture *pic;
pic = malloc(sizeof(*pic));
UploadFile(pic);
*tab = temp;
(*tab)[(*PicCounter)-1] = *pic;
free(pic);
}
else {
printf("Memory reallocation error");
free(*tab);
(*PicCounter)--;
return 1;
}
return 0;
}
它并不完美,但可以正常工作。感谢您的帮助!
我正在尝试使用 realloc 创建结构的动态数组(在本例中为图片)。我想在函数中这样做,但是有一个问题:main 中的变量不会被这个函数改变。指针一定有问题,但我找不到它。 PS: 函数 UploadFile 工作正常。 有一个函数:
int AddPicture(struct Picture ***tab, int *PicCounter)
{
struct Picture *temp;
struct Picture pic;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) *sizeof(*temp));
if (temp != NULL)
{
UploadFile(&pic);
**tab = temp;
(*tab)[*PicCounter-1]->name = pic.name;
(*tab)[*PicCounter-1]->type[0] = pic.type[0];
(*tab)[*PicCounter-1]->type[1] = pic.type[1];
(*tab)[*PicCounter-1]->width = pic.width;
(*tab)[*PicCounter-1]->height = pic.height;
(*tab)[*PicCounter-1]->scale = pic.scale;
(*tab)[*PicCounter-1]->table = pic.table;
}
else {
printf("Memory reallocation error");
free(temp);
return 1;
}
return 0;
}
我是这样称呼它的:
struct Picture *tabofpics;
int piccounter = 0;
tabofpics = malloc(1 * sizeof(*tabofpics));
AddPicture(&tabofpics,&piccounter);
感谢您的帮助。
编辑: 我试过 **tab 而不是 ***tab 并且 main 中的值是正确的,但它的行为就像内存没有正确重新分配,即使 realloc 没有 return NULL。
int AddPicture(struct Picture **tab, int *PicCounter)
{
struct Picture *temp;
struct Picture pic;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) * sizeof(*temp));
if (temp != NULL)
{
UploadFile(&pic);
*tab = temp;
tab[*PicCounter - 1]->name = pic.name;
tab[*PicCounter - 1]->type[0] = pic.type[0];
tab[*PicCounter - 1]->type[1] = pic.type[1];
tab[*PicCounter - 1]->width = pic.width;
tab[*PicCounter - 1]->height = pic.height;
tab[*PicCounter - 1]->scale = pic.scale;
tab[*PicCounter - 1]->table = pic.table;
}
else {
printf("Memory reallocation error");
free(*tab);
return 1;
}
return 0;
}
这个想法是在程序中放多少张图片就放多少张,对其进行一些操作然后离开。必须有添加和删除图片的功能,只要用户想要,但是当我第二次在参数中使用 **tab 调用函数时,我得到了访问冲突位置,所以正如我之前提到的,realloc 一定不能正常工作。
在我看来,您需要改进代码的逻辑,例如
- 还不递增
PicCounter
- 您的指针间接级别不匹配,在调用函数中您有
struct Picture *
并且您将其作为struct Picture **
传递给采用struct Picture ***
的函数。您应该对此进行推理,以及您真正想要的是什么。看来你想要一个struct Picture *
. 的数组
风格,
- 不要使用
PicCounter
作为变量,使用number_of_pictures
或更合适的东西。 - 不要写
1 * sizeof(...)
它太露骨了,你不需要那么多。
工具,
- 启用编译器警告以发现您在没有注意到的情况下犯下的简单错误,或者那些概念上的错误,例如代码中指针的间接寻址不匹配。
也就是说,我想你可能想写这个
int
AddPicture(struct Picture ***tab, int *counter)
{
struct Picture **array;
array = realloc(*tab, (*counter + 1) * sizeof(*array));
if (array != NULL)
{
struct Picture *current;
// We will avoid using the `tab' variable because it's
// confusing, the only reason why it's a *** pointer is
// to do this here, and below where we set it to `NULL'
*tab = array;
// We also need to allocate space for a new image to store
// the results in.
current = malloc(sizeof(*current));
if (current == NULL)
goto error;
// This is a guess, but isn't the code just initializing
// the `pic' that you allocated on the stack?
//
// Well, the following is the same.
//
// Oh, and should we check for errors here?
UploadFile(current);
// Now we can increase counterand update our array
array[(*counter)++] = current;
// We have succeded, so return 0
return 0;
}
error:
printf("Memory reallocation error");
// Release memory allocated so far
free(*tab);
// Prevent dangling pointer
*counter = 0;
*tab = NULL;
// A non zero value means, an error
return 1;
}
调用函数应该是这样的
struct Picture **tabofpics;
int counter = 0;
// `realloc' will take car of the allocation
tabofpics = NULL;
if (AddPicture(&tabofpics, &picounter) == 0)
// Everything ok, picture added
else
// Error
请小心 ***
指针,它们会引起很多混乱。我要考虑四五次
(*tab)[*counter] = current;
在我看到它是正确的之前。所以我选择更改它,如您在代码中看到的那样。
您的代码应尽可能具有描述性,使用 ***
指针会导致错误的方向。
您的代码中的以下两个摘录或许可以最好地概括核心问题:
temp = realloc(*tab, (*PicCounter) *sizeof(*temp));
[...]
**tab = temp;
您正在重新分配由 *tab
的值指向的 space,但成功后,您将指向新 space 的指针存储在 **tab
中,这是一个不同的位置。不管哪一个是指针的正确位置,组合肯定是错误的。
然而,事实上,考虑到您调用函数的方式...
struct Picture *tabofpics;
[...]
AddPicture(&tabofpics,&piccounter);
...实参的类型是struct Picture **
。这适合您的目的,因此您应该调整函数定义以匹配:
int AddPicture(struct Picture **tab, int *PicCounter)
。此外,您应该确保头文件中存在匹配的函数声明,该头文件 #include
d 进入包含 AddPicture
定义的源文件以及包含对该函数的调用的每个源文件。再加上确保出现编译器警告,编译器应该能够帮助您诊断此函数的定义和使用之间的不匹配。
完成后,函数 AddPicture()
中的表达式 *tab
将引用表达式 tabofpics
(无 *
)在 main()
。这似乎与您实际使用它的方式一致,但我在开头描述的不匹配除外。
可以对您的代码提出其他合理的批评,但@Iharob 已经在他的回答中很好地解决了这些问题。
根据@Iharob 和@John 的回答,我能够编写一个工作函数:
int AddPicture(struct Picture **tab, int *PicCounter)
{
struct Picture *temp;
(*PicCounter)++;
temp = realloc(*tab, (*PicCounter) * sizeof(*temp));
if (temp != NULL)
{
struct Picture *pic;
pic = malloc(sizeof(*pic));
UploadFile(pic);
*tab = temp;
(*tab)[(*PicCounter)-1] = *pic;
free(pic);
}
else {
printf("Memory reallocation error");
free(*tab);
(*PicCounter)--;
return 1;
}
return 0;
}
它并不完美,但可以正常工作。感谢您的帮助!