簡體   English   中英

C-重新分配指針,它是struct的屬性:將指針解引用為不完整類型

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

RCBstruct 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 RCBRCB之間沒有關系。 特別是在此代碼中:

typedef struct {
  struct RCB *next;
  struct RCB *prior;
} RCB;

next不指向RCB 它指向的struct RCBRCB完全不同。 這就是為什么出現錯誤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_rcbblah函數的局部變量。 blah返回時, new_rcb停止存在。 這意味着RRhead指向的列表將包含一個懸空指針。

使用指針時,您需要非常清楚地了解指針指向的位置以及所指向的對象的壽命。

要解決此問題,您可以使用動態分配( malloc )或某種內存池。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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