[英]C - reassigning pointer which is attribute of struct: dereferencing pointer to incomplete type
我可以肯定地說,我對C中的指針有一個可怕的了解(至少在語法上)。
我試圖有一個結構,它是帶有大量數據的鏈表。 稍后,我嘗試添加一個新結構作為該鏈表的頭,指向舊頭,該舊頭具有指向新頭的“先前”鏈接。
typedef struct{
int sequence_number;
int file_descriptor;
FILE *requested_file;
int bytes_remaining;
int quantum;
struct RCB *next;
struct RCB *prior;
} RCB;
RCB *RRhead;
...
function blah(){
RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
RRhead->prior = &new_rcb;
RRhead = &new_rcb;
sequence_counter++;
}
我收到這些錯誤:
sws.c: In function ‘admit_to_scheduler_RR’:
sws.c:317:3: warning: initialization from incompatible pointer type [enabled by default]
RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
sws.c:317:3: warning: (near initialization for ‘new_rcb.next’) [enabled by default]
sws.c:318:17: warning: assignment from incompatible pointer type [enabled by default]
RRhead->prior = &new_rcb;
RCB
和struct RCB
是兩種完全不同的,無關的類型。 struct RCB
從未在您的代碼中定義,因此不完整。
為了使它們相同,寫
typedef struct RCB {
....
} RCB;
這是問題的一部分。
初始化new_rcb
時不要使用*RRhead
new_rcb
。 您只需要RRhead
。
該結構具有一個指針,即struct RCB *prior
因此您必須使用指針RRhead
。
首先,RRhead只是一個指針,所以當您轉到RRhead-> prior時,會遇到運行時錯誤,因為RRhead沒有指向任何內容(RRhead-> prior說“獲取RCB結構的'優先'屬性, RRhead指向)
其次,當您傳遞* RRhead作為new_rcb的最后一個初始化程序時:Prior是RCB指針,而RRhead是RCB指針。 它們是同一類型,因此無需進行任何引用或取消引用,只需傳遞RRhead。 這將使new_rcb的先前屬性指向當時RRhead指向的內容(當時不存在,因為RRhead尚未初始化為任何值)
第三,RRhead-> prior = new_rcb; 這是錯誤的,因為'prior'是RCB指針,而new_rcb不是指針,而是RCB。 要傳遞new_rcb的地址,請轉到RRhead-> prior =&new_rcb;
最后,不太可能需要靜態分配new_rcb。
這里有很多問題。 由於您不斷更改它,因此尚不清楚您的真實代碼是什么,但我會遇到一個困難:
首先,在C語言中,結構標記位於單獨的“命名空間”中,以鍵入typedef名稱。 struct RCB
和RCB
之間沒有關系。 特別是在此代碼中:
typedef struct {
struct RCB *next;
struct RCB *prior;
} RCB;
next
不指向RCB
。 它指向的struct RCB
與RCB
完全不同。 這就是為什么出現錯誤error: dereferencing pointer to incomplete type
。 您從未定義過struct RCB
。
如果要包含指向其自身的指針的結構,則必須使用struct標記,因為在完成typedef之前,typedef名稱不存在。 例如:
struct RCB
{
// ...
struct RCB *next, *prior;
};
typedef struct RCB RCB;
當然,typedef是可選的; 可以與struct定義結合使用,但我認為將兩者分開更清晰。
下一個問題是:
new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
在C語言中不允許這樣做,賦值運算符的右側必須是一個表達式。 用大括號括起來的列表不是表達式。 避免此問題的最簡單方法是使用初始化:
RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
最新的編輯提示了另一個運行時問題:
function blah(){
RCB new_rcb = {sequence_counter, fd, fin, new_bytes_remaining, new_quantum, RRhead, NULL};
RRhead->prior = &new_rcb;
RRhead = &new_rcb;
sequence_counter++;
}
顯然,這是某種偽代碼。 但是new_rcb
是blah
函數的局部變量。 當blah
返回時, new_rcb
停止存在。 這意味着RRhead
指向的列表將包含一個懸空指針。
使用指針時,您需要非常清楚地了解指針指向的位置以及所指向的對象的壽命。
要解決此問題,您可以使用動態分配( malloc
)或某種內存池。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.