簡體   English   中英

類型轉換結構指針

[英]Type casting struct pointer

我正在嘗試進行Socket編程,並在https://www.tenouk.com/Module43a.html上遇到了一篇文章,由於將char數組如何轉換為結構指針,我很難理解

char buffer[PCKT_LEN];
struct ipheader *ip = (struct ipheader *) buffer;
//some code here
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;

根據我的理解,指針ip現在將保存緩沖區的地址,而struct ipheader成員的值現在將存儲在緩沖區中。 請幫助理解相同的。 如果我是對的,那我們將如何打印存儲在緩沖區中的值?

您的理解是正確的。 指針* ip將指向緩沖區。 char buffer [PCKT_LEN]是一個大小為sizeof(char)* PCKT_LEN的數組。 由於char通常為1個字節長,因此它只是PCKT_LEN個字節的內存塊。 PCKT_LEN定義為8192

存儲一個struct ipheader所需的字節數比這少得多。 嘗試int a = sizeof(ipheader)和使用調試器看分配給值a 對我來說,它是24個字節,但是對您來說可能略有不同。 這意味着緩沖區可以容納的數據超過了struct ipheader所需的數據。 我沒有深入研究代碼,對套接字編程也不太了解。 但是,這樣做的一種用途可能是在結構外部添加額外的數據來增加緩沖區。 因為您知道struct ipheader占用了sizeof(ipheader)個字節,所以您將獲得sizeof(char)* 8192-剩下的sizeof(ipheader)可以增加數組。

編輯:Upun進一步檢查,這是正在發生的事情:

struct ipheader *ip = (struct ipheader *) buffer;
struct udpheader *udp = (struct udpheader *) (buffer + sizeof(struct ipheader));

它嘗試將ip標頭存儲在緩沖區的開頭,然后使用udp標頭擴展該緩沖區。 通過使用buffer + sizeof(struct ipheader)它通過將buffer + sizeof(struct ipheader)偏移sizeof(struct ipheader)個字節來確保它 ipheader 之后存儲udp頭。 基本上struct ipheader *ip指向緩沖區的開頭,而struct udpheader *udp指向buffer + sizeof(struct ipheader) 我希望這是有道理的。 顯然,緩沖區中還剩下很多空間,因此您可能會進一步擴大它。

如何將char數組轉換為struct指針

您不能安全地這樣做。 該代碼調用未定義的行為:

char buffer[PCKT_LEN];
struct ipheader *ip = (struct ipheader *) buffer;
//some code here
ip->iph_ihl = 5;
ip->iph_ver = 4;
ip->iph_tos = 16;

該代碼違反了嚴格的別名規則 基本上,這意味着不是某種對象類型的內存不能被視為該類型的對象,除了任何非char對象都可以視為char數組。

那不是發布的代碼中發生的事情。 在發布的代碼中,將char數組視為是struct ipheader

內存不是一個struct ipheader ,而是一個char數組,因此代碼違反了嚴格的別名。

char *struct ipheader *還可能導致對象對齊不正確並違反6.3.2.3指針第7段

指向對象類型的指針可以轉換為指向不同對象類型的指針。 如果結果指針未針對引用類型正確對齊,則該行為未定義。 ...

不幸的是,您在這里發現的代碼非常普遍,因為基於x86的計算機是程序員廣泛使用的最常見的平台,它們非常寬容錯位的訪問,因此此類代碼易於“工作”。

請參閱Linux中的結構分配在ARM上失敗,但在x86上成功在不起作用的平台上進行說明。

暫無
暫無

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

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