C語言 結構體指標強制轉換

2021-08-01 18:18:27 字數 2597 閱讀 5258

最近寫c程式遇到的結構體指標強轉的坑,記錄一下.

是乙個簡單的選單程式,程式用到鍊錶,表中儲存了9個不同命令.每次將使用者輸入的命令與表中儲存的命令名作對比(遍歷查詢),然後執行相應功能.

總體結構:

linktable.h:定義通用模組化鍊錶資料結構,以及相關操作

linktable.c:實現標頭檔案中定義的鍊錶操作

main.c:主函式

通用鍊錶節點:(抽象定義)

typedef

struct linktablenode

tlinktablenode;

鍊錶:

typedef

struct linktable

tlinktable;

資料節點:(通用鍊錶的具體化)

typedef

struct datanode

tdatanode;

main.c片段:

tdatanode * findcmd(tlinktable *head, char *cmd)//函式:遍歷鍊錶head,查詢與cmd符合的命令並返回該資料節點

pnode = (tdatanode*)getnextlinktablenode(head, (tlinktablenode*)pnode);

}return null;

}//對資料節點賦值,注意每個欄位的擺放順序要與定義的格式相匹配

static tdatanode menu =,,

,,,,

,,};//初始化,建立鍊錶體,並把頭尾分別指向menu[0]和menu[8]

int initmenudata(tlinktable **pplinktable)

tlinktable *head = null;

int main()

printf("%s ---- %s\n", p->cmd, p->desc);//輸出該命令資訊

if(p->handler != null)}}

看起來沒有什麼問題,執行,崩潰.進入除錯,發現原因在於main片段的第11行

pnode =(tdatanode*)getnextlinktablenode(head, (tlinktablenode*)pnode);
getnextlinktablenode的功能是返回鍊錶head中pnode節點的下乙個節點.這裡對引數pnode(第4行建立為tdatanode*型別)進行強制轉換成tlinktablenode *型別.

然而我們知道,強制轉換是有可能出問題的,這就是問題所在.tlinktablenode是乙個通用的鍊錶節點型別,其中只包含乙個後繼域 pnext,而tdatanode包含了四個成員:兩個char陣列指標cmd和desc,還有函式指標handler和後繼pnext.如此一來強轉必然出問題.

執行第11行前,除錯的資訊如圖所示:

pnode的型別為tdatanode*,其cmd欄位為0x406070(「version」),pnext欄位為0x405030

進入11行後,除錯資訊發生如下變化:

pnext型別為tlinktablenode*,其中pnext欄位為0x406070.是不是很熟悉?沒錯,就是強制轉換之前的cmd欄位內容.也就是說,pnext本該指向0x405030,卻因為強制轉換而變成了0x406070.而這是乙個未知的位址,也就是常說的」指標亂指」,如此一來發生錯誤是必然的!

可以看到,結構體陣列的位址都是非常規整的,他們彼此相鄰,每個結構體占0x10的位址空間,然而由於指標亂指到未知的位址0x406070,進入該位址後,pnext繼續亂指到0x73726576.再進入這個位址,讀取其cmd欄位,系統報告發生段錯誤,程式終止.

那麼正確的做法是什麼呢?觀察強制轉換的內容,可以發現強轉成tlinktablenode*後,pnext的內容為tdatanode *的cmd內容,也就是定義結構體中的第乙個字段,要想保持強轉後不丟失後繼指標,只有在定義結構體時將後繼指標調整到第乙個字段:

typedef

struct datanode

tdatanode;

同時對結構體陣列賦值時也要注意順序的調整,把後繼指標的賦值放在第一位:

static tdatanode menu =,,

,,,,

,,};

這樣程式才能正常運

結構體指標強制型別轉換

這兩天整結構體指標強制型別轉換的問題,真好碰到乙個的乙個問題,我把這個問題例項化實現,發現這個例項對弄清楚下面三個問題有很大幫助 1,結構體指標強制型別轉換的問題 2,char字元cout輸出的問題 3,結構體資料對齊的問題 具體下面的例項有分析 include using namespace st...

c語言struct結構體強制型別轉換

1 無結構體標籤 struct gpio t 宣告了乙個無名結構體,並建立了乙個結構體變數gpio t 已分配空間 該方法只適合建立乙個結構體變數 typedef struct gpio t 靜態分配記憶體 gpio t gpioa 動態分配記憶體 gpio t gpioa gpio t mallo...

C語言指標強制型別轉換

一 舉例說明 上圖對應函式呼叫為int printf const char fmt,fmt為char 指標型別,所以共佔了32位位元組,但是 fmt執行的是乙個位元組,fmt 執行的是下乙個位元組,fmt得到乙個32位位址,char fmt得到是乙個執行位元組的指標,char fmt 4後正好執行了...