我希望有人能帮我弄清楚为什么下面的代码一个版本可以工作,而另一个版本不行。此函数在main中访问,两个版本如下所示。
void initArray(struct dynArray *a) {
a->data = malloc(10 * TYPE_SIZE);
assert(a->data != 0);
a->size = 0;
a->capacity = 10;
}
这很管用。我创建一个dynArray结构并通过引用将其传递给initArray。
#include "worksheet0.h"
#include <stdio.h>
int main(void)
{
struct dynArray b;
initArray(&b);
return 0;
}
这会因seg故障而失败。我认为在这里传递
b
与通过引用传递结构是一样的。int main(void)
{
struct dynArray *b = NULL;
initArray(b);
return 0;
}
最佳答案
因为在第二种情况下,没有分配结构指针指向的内存。它只是一个值NULL
的指针。在您的情况下,通过取消对值NULL
的引用,您已经调用了未定义的行为。
如果您分配内存,对其进行更改,然后返回其值,它就会工作。[但是,您必须返回分配内存的地址],或者您可以传递指针变量的地址并分配取消引用指针(这里指针的类型是struct dynAray**
)将指向的内存并对其进行更改。
现在让我们慢慢说清楚:
为什么第一个案子有效?您有一个struct dynArray
变量,您已将其地址传递给函数,然后您已访问该地址的内容-等等!这意味着您已经访问了struct dynArray
变量本身并对其成员变量进行了更改。是的,第一个案子就是这样的。
在第二种情况下,您有一个指向struct dynArray
的指针。然后你传递了它-去引用它。它指向哪里?它包含变量的地址吗?不,是struct dynArray
。所以,如果你希望它起作用,那就错了。
第二个是可行的,但是你必须改变一点!让我们看看如何:
struct dynArray* initArray() {
struct dynArray* a = malloc(sizeof *a);
assert(a != NULL);
a->data = malloc(10 * TYPE_SIZE);
assert(a->data != 0);
a->size = 0;
a->capacity = 10;
return a;
}
在
NULL
struct dynArray* b;
b = initArray();
您甚至不需要传递指针变量。如果你想这样做那就没有意义了。
您还可以传递指针变量的地址,以便对其进行更改-
void initArray(struct dynArray** a) {
*a = malloc(sizeof **a);
assert((*a) != NULL);
(*a)->data = malloc(10 * TYPE_SIZE);
assert((*a)->data != 0);
(*a)->size = 0;
(*a)->capacity = 10;
}
对于
main()
中的这个,您可以这样称呼它struct dynArray* b;
initArray(&b);
关于c - 通过地址与C中的指针将结构传递给函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48435265/