簡體   English   中英

通過地址與C中的指針將結構傳遞給函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM