[問題] 指標的轉型問題

看板C_and_CPP作者 (我愛阿蓉)時間12年前 (2012/02/09 17:28), 編輯推噓0(0014)
留言14則, 6人參與, 最新討論串1/1
大家好, 最近在研究一個API, 雖然成功使用 卻不解他的設計方式.... http://msdn.microsoft.com/en-us/library/ms919833.aspx 他最後 PBT_POWERINFOCHANGE 這個case會傳一個structure如下 http://msdn.microsoft.com/en-us/library/ms919667.aspx 他Remark 部分有寫到 The POWER_BROADCAST structure has a variable length. The SystemPowerState array is a placeholder for data associated with the message being broadcast and is not always WCHAR data. 這邊我就覺得很不解 如果是我自己寫 該怎麼做一個會變動長度的structure 於是我去google一下他該怎麼轉型, 因為MSDN也沒範例程式 http://tinyurl.com/7h26s88 PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) &pbb.SystemPowerState[0]; 他就直接把第四個field轉成他所說的型態 結果確實可以work 於是我去意測他的作法 struct _POWER_BROADCAST_REAL { DWORD Message; DWORD Flags; DWORD Length; VOID* ptr; }; //我猜他實際上是new這個型態 struct _POWER_BROADCAST { DWORD Message; DWORD Flags; DWORD Length; WCHAR ptr[1]; }; struct _POWER_BROADCAST_POWER_INFO { int data; }; int main() { _POWER_BROADCAST_POWER_INFO Data; Data.data = 5566; _POWER_BROADCAST_REAL* realObject = (_POWER_BROADCAST_REAL*)malloc(sizeof(_POWER_BROADCAST_REAL)); realObject->Message = 7788; realObject->Length = 123; realObject->ptr = &Data; //指到實際的物件 // _POWER_BROADCAST* fakeType = (_POWER_BROADCAST*)realObject; //先印出message, 成功 cout<<fakeType->Message<<endl; //學 網路上都這種寫法 _POWER_BROADCAST_POWER_INFO* ptr2 =     (_POWER_BROADCAST_POWER_INFO*)fakeType->ptr; //印出怪值 cout<<ptr2->data; } 我大概知道為啥我會印出怪值 因為我_POWER_BROADCAST::ptr 是一個static array 他似乎就直接得到 fakeType->Length address + 4 所以我必須改成 轉型兩次 _POWER_BROADCAST_POWER_INFO *ptr2 = (_POWER_BROADCAST_POWER_INFO *)(((_POWER_BROADCAST*)fakeType)->ptr); cout<<ptr2->data<<endl; 這樣才會得到正確值~~ 令我不解的就是 為啥MSDN的這種用法 直接轉型沒有後顧之憂 如果是我猜測錯誤 那還有什麼做法能夠 達成他的可變動長度... 實在是不解 煩請各位給予指正 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 219.87.64.222

02/09 17:39, , 1F
大概只有這樣而已 http://ideone.com/XIzAT
02/09 17:39, 1F

02/09 19:19, , 2F
可參考 gcc.gnu.org/onlinedocs/gcc/Zero-Length.htm
02/09 19:19, 2F

02/09 23:56, , 3F
簡單講就是在malloc的空間區段內 怎麼解釋這塊記憶體都OK嚕?
02/09 23:56, 3F

02/10 00:05, , 4F
是啊,一開始拿大一點的空間,多出來的都隨便你用
02/10 00:05, 4F

02/10 09:58, , 5F
WCHAR ptr[1];<-c99允許structure的最後一個成員為未定
02/10 09:58, 5F

02/10 09:59, , 6F
大小的陣列.可以根據malloc去配置最後一個成員的大小
02/10 09:59, 6F

02/10 10:01, , 7F
樓上大師可以回覆一篇文章嗎 XDDD
02/10 10:01, 7F

02/10 10:03, , 8F
超哥...不是會了嘛?
02/10 10:03, 8F

02/10 10:21, , 9F
我猜可變動的原因在WCHAR ptr[1];<-其實按照c99的標準
02/10 10:21, 9F

02/10 10:22, , 10F
應該要是WCHAR ptr[]; 只是我在gcc會看[0],vc會看到[1]
02/10 10:22, 10F

02/10 10:24, , 11F
Favonia已經點出來這點了!只是有錯的話,請大家糾正了喔
02/10 10:24, 11F

02/10 11:22, , 12F
#1DhhMrOO (C_and_CPP) 是否有異曲同工之妙?
02/10 11:22, 12F

02/10 12:46, , 13F
的確我想到樓上提到的文章XD
02/10 12:46, 13F

02/10 13:38, , 14F
基本上就像tropical72所說那樣,期待大師回一篇好文
02/10 13:38, 14F
文章代碼(AID): #1FCv6z65 (C_and_CPP)