在C中通过地址与指针将结构传递到函数
我希望有人能帮我弄明白为什么下面代码的一个版本可以工作,而另一个版本不行。下面我介绍了存储在“worksheet.c”中的initArray方法。该函数在main中访问,下面给出了两个版本在C中通过地址与指针将结构传递到函数,c,pointers,struct,C,Pointers,Struct,我希望有人能帮我弄明白为什么下面代码的一个版本可以工作,而另一个版本不行。下面我介绍了存储在“worksheet.c”中的initArray方法。该函数在main中访问,下面给出了两个版本 void initArray(struct dynArray *a) { a->data = malloc(10 * TYPE_SIZE); assert(a->data != 0); a->size = 0; a->capacity = 10;
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;
}
int main(void)
{
struct dynArray *b = NULL;
initArray(b);
return 0;
}
因为在第二种情况下,没有分配结构指针指向的内存。它只是一个具有值
NULL
的指针。在您的案例中,通过取消引用值NULL
调用了未定义的行为
如果您分配内存,对其进行更改,然后返回它的值,它就会工作。[但您必须返回分配内存的地址。]或您可以传递指针变量的地址,并分配取消引用的指针(此处指针的类型为struct dynAray**
)将指向的内存,并对其进行更改。
让我们慢慢地说清楚:
为什么第一个案例有效?您有一个struct dynArray
变量,该变量的地址已传递到函数中,然后您访问了该地址的内容-等等!这意味着您已经访问了struct dynArray
变量本身,并对其成员变量进行了更改。是的,第一个案例就是这样的
在第二种情况下,您有一个指向struct dynArray
的指针。然后你传递了它-取消引用了它。它指的是哪里?它包含的是某个struct dynArray
变量的地址吗?没有。它是NULL
。因此,如果你期望它能起作用,那就错了
第二种方法可行,但你必须改变一些事情!让我们看看如何:
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;
}
在main()中
您甚至不需要传递指针变量。如果你想这样做,那就没有意义了
您知道,您还可以传递指针变量的地址,以便对其进行更改-
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);
因为在第二种情况下,没有分配结构指针指向的内存。它只是一个具有值NULL
的指针。在您的案例中,通过取消引用值NULL
调用了未定义的行为
如果您分配内存,对其进行更改,然后返回它的值,它就会工作。[但您必须返回分配内存的地址。]或您可以传递指针变量的地址,并分配取消引用的指针(此处指针的类型为struct dynAray**
)将指向的内存,并对其进行更改。
让我们慢慢地说清楚:
为什么第一个案例有效?您有一个struct dynArray
变量,该变量的地址已传递到函数中,然后您访问了该地址的内容-等等!这意味着您已经访问了struct dynArray
变量本身,并对其成员变量进行了更改。是的,第一个案例就是这样的
在第二种情况下,您有一个指向struct dynArray
的指针。然后你传递了它-取消引用了它。它指的是哪里?它包含的是某个struct dynArray
变量的地址吗?没有。它是NULL
。因此,如果你期望它能起作用,那就错了
第二种方法可行,但你必须改变一些事情!让我们看看如何:
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;
}
在main()中
您甚至不需要传递指针变量。如果你想这样做,那就没有意义了
您知道,您还可以传递指针变量的地址,以便对其进行更改-
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);
在第一个示例中,将保存实际struct
地址的指针传递给函数。但是,在第二个示例中,指针b
不指向struct
。相反,此指针被初始化为NULL
,当此空指针在initArray()
函数中被取消引用时,会出现未定义的行为。在第一个示例中,将保存实际结构的地址的指针传递给函数。但是,在第二个示例中,指针b
不指向struct
。相反,此指针初始化为NULL
,当此空指针在initArray()
函数中被取消引用时,会出现未定义的行为。将值NULL
传递给void initArray(struct dynArray*a)
然后a->data
derefrencesNULL
;c->size=0你认为这样行吗?(回答之前不要尝试)当您将值NULL
传递给void initArray(struct dynArray*a)
时,然后a->data
derefrencesNULL
。如果您编写了struct dynArray*c=NULL;c->size=0你认为这样行吗?(回答前不要尝试)