提问人:Zeta-Squared 提问时间:6/4/2022 最后编辑:Zeta-Squared 更新时间:6/4/2022 访问量:51
内存分配函数返回的点
Points returned by memory allocation functions
问:
我正在从 K.N.King 的书中学习 C,并且正在完成第 17 章的编程项目。我在完成第一个项目时遇到了一个自作自受的错误。这是程序的未定义行为,因为我正在向 realloc() 传递从早期 malloc() 调用返回的指针的副本,因为 realloc() 调用发生在 main() 以外的函数中。在重新阅读了本章的部分内容后,我意识到 realloc() 在这种情况下具有未定义的行为。
我试图寻找为什么会这样,但无济于事。那么,这里有人知道为什么传递给 realloc() 的指针必须是从 malloc()、calloc() 或 realloc() 的早期调用返回的指针,而不是这些指针的副本?另外,每当我们想要调整内存块的大小时,我们不是天生就总是复制 realloc() 返回的指针吗?
int num_parts = 0, max_parts = 10;
int main(void)
{
struct part *inventory = malloc(max_parts * sizeof(*inventory));
\\...
switch(ch) {
\\...
case 'i':
insert(inventory, &num_parts, &max_parts);
break;
\\...
}
}
void insert(struct part *inventory, int *num_parts, *max_parts)
{
if (*num_parts == *max_parts) {
*max_parts += 10;
struct part *temp = realloc(inventory, max_parts * sizeof(*temp));
if (temp != NULL)
inventory = temp;
else
printf("Error:...\n");
}
\\...
}
答:
4赞
Vlad from Moscow
6/4/2022
#1
该函数按值接受指针insert
inventory
void insert(struct *inventory, int *num_parts, *max_parts)
和
insert(inventory, &num_parts, &max_parts);
这意味着该函数处理原始指针值的副本。在函数中更改副本,例如
if (temp != NULL)
*inventory = temp;
不影响 main 中声明的原始指针的值。
您需要通过指向指针的指针通过引用传递指针。
那是
insert( &inventory, &num_parts, &max_parts);
该功能将看起来像
void insert(struct **inventory, int *num_parts, *max_parts)
{
if (*num_parts == *max_parts) {
*max_parts += 10;
struct part *temp = realloc( *inventory, max_parts * sizeof(*temp));
if (temp != NULL)
*inventory = temp;
else
printf("Error:...\n");
}
\\...
}
在这种情况下,取消引用函数中的函数参数,我们可以直接访问原始指针(对象),从而可以更改它。struct **inventory
评论
0赞
Zeta-Squared
6/4/2022
啊,好吧。我认为这应该与数组相同,通过向函数传递数组的名称,我们只是将指针传递到数组的第一个元素,但我们仍然可以以这种方式操作数组的元素?
0赞
Vlad from Moscow
6/4/2022
@Zeta平方 事实上,我们通过指向数组第一个元素的指针通过引用传递数组的元素。使用指针算术和取消引用运算符,我们可以更改数组的任何元素。同样,如果我们要在函数中更改指针的值,我们需要通过引用(通过指向它的指针)传递指针。
0赞
Zeta-Squared
6/4/2022
是的,谢谢你,我现在明白了。对于数组,将数组名称传递给函数不会更改指针指向的内容,而是更改所指向的对象。在这种情况下,我已经提出,由于内存块我位于完全不同的位置,我需要能够更改指针指向的内容,因此我需要将原始指针的地址传递给函数,即 .谢谢你的帮助,我已经接受了你的回答。struct part **inventory
0赞
ShadowRanger
6/4/2022
@Zeta平方:需要明确的是,问题不在于您传递了指针的副本。没关系,无法分辨区别(如果您开始 Vlad 的函数并传递给 ,它会正常工作)。问题在于您需要替换调用方的原始指针,如果没有指向调用方存储的指针,则无法做到这一点。realloc
realloc
struct part *localinventory = *inventory;
localinventory
realloc
0赞
Zeta-Squared
6/4/2022
@ShadowRanger 是的,我现在明白了。谢谢。
评论