我有一個數據結構,鏈表,它看起來像傳遞一個指針的指針VS傳遞一個指針初始化用C
struct listitem {
void* data;
struct listitem* next;
};
typedef struct listitem listitem;
typedef struct {
listitem* head;
pthread_rwlock_t lock;
} linkedlist;
我用一個指針到void *的數據,因爲我想使數據結構具有多態性,以便我可以將它用於幾個不同的應用程序。
要初始化列表(分配內存並初始化rw鎖),我將它傳遞給函數 init_list(..)。當我通過指針如下列表中,該程序掛起,每當我試圖名單上執行任何進一步的操作(如推一個項目的話):
int init_list(linkedlist* list /* borrowed - list to initialise (probably unallocated) */) {
list = (linkedlist*)calloc(1, sizeof(linkedlist)); // clear the memory, so that head is a null pointer
printf("Allocated memory\n");
if (list == 0) {
perror("calloc failed on allocating memory for list");
return 1;
}
printf("Initialising lock\n");
pthread_rwlock_init(&list->lock, NULL);
return 0;
}
...
linkedlist* ll;
init_list(ll);
這是我的理解是,上述應清除ll指向的內存,並適當地初始化鎖的內存位置。然而,當我將指針傳遞給列表指針時,它一切正常(即,當我嘗試執行進一步的操作(例如獲取鎖並將項目推送到列表中)時,程序不會掛起)。我不明白爲什麼添加這個額外的間接層使其工作。無論我如何引用它們,我都認爲在實際內存位置上的操作是相同的?
即以下工作,而第一種方法不會:
int init_list(linkedlist** list /* borrowed - list to initialise (probably unallocated) */) {
*list = (linkedlist*)calloc(1, sizeof(linkedlist)); // clear the memory, so that head is a null pointer
printf("Allocated memory\n");
if (list == 0) {
perror("calloc failed on allocating memory for list");
return 1;
}
printf("Initialising lock\n");
pthread_rwlock_init(&(*list)->lock, NULL);
return 0;
}
...
linkedlist* ll;
init_list(&ll);
我無法解釋爲什麼第二個方法效果先不時。
就一般風格而言,這種方式常見嗎?或者有更好的,更常見的方式來初始化C中的數據結構?我是一個相對較新的C程序員,來自面向對象的語言,我期望在構造函數中做這樣的初始化,而且我很善良 - 試圖用C來複制這種風格,考慮它 - 可能不一定是合乎邏輯的?
謝謝!我已更新我的代碼以返回指向已初始化鏈接列表的指針,而不是像當前那樣返回0或1。 – Froskoy