[英]Passing structs into function by address vs a pointer in C
我希望有人能幫我弄清楚為什么以下代碼的一個版本可以工作,而另一個版本不能工作。 下面,我包含了存儲在“ 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;
}
這可行。 我創建了一個dynArray結構,並將其通過引用傳遞給initArray。
#include "worksheet0.h"
#include <stdio.h>
int main(void)
{
struct dynArray b;
initArray(&b);
return 0;
}
這會因段錯誤而失敗。 我認為在這里傳遞b
與通過引用傳遞struct相同。
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
變量的地址嗎? 不,這是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()
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);
在第一個示例中,將保存實際struct
地址的指針傳遞給該函數。 但是,在第二個示例中,指針b
沒有指向struct
。 相反,此指針被初始化為NULL
,並且在initArray()
函數中取消引用此空指針時,將發生未定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.