VC++ 6.0 結構定義大陷阱 (轉)
VC++ 6.0 結構定義大陷阱!!!
本人寫一個,定義一個引數型別
typedef struct tagDef_Param
{
char Name[64];
bool Need;
bool Neeuf;
int Type;
}DEF_PARAM, *PRT_DEF_PARAM;
為了方便,所用的引數內容透過來維護,並透過VBA宏將引數內容寫入,然後再由VC。
為此本人在VBA中定義了一個結構
Type vbDef_Param
Name as string * 64
Need as byte
NeedBuf as byte
Type as long
End Type
從MSDN中所描述的型別長度來計算VC中定義的結構長度應為70 = char(1) * 64 + bool(1) + bool(1) + int(4), VBA中定義的也應是70 = 64 + 1 + 1 + 4。
但實際結果卻不正確,在VC、VB中分別用以下程式碼得出的結果如下:
/* VC++ */
printf("Len=%d",sizeof(DEF_PARAM));
//輸出結果為Len=72
' VB
Dim Buf as vbDef_Param
Msgbox(Len(Buf))
'得到的結果是70
VC的結果比設想的多出了2個Byte,而VB卻正確?!
為了看看VC到底多在了那,又用以下程式測試了一下
/* VC++ */
PRT_DEF_PARAM pDP = new DEF_PARAM;
pDP->Need = 0;
pDP->NeedBuf = 0;
pDP->Type = -1;
for(int I = 0; I < 64; I++)
pDP->Name[I] = '*';
CFile ;
sf.open(......);
sf.write(pDP, sizeof(DEF_PARAM);
sf.close();
/*End*/
最後得到的結果竟然是讓人意想不到的,見下(UltraEdit 7.0):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
-----------------------------------------------
2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
00 00 CD CD FF FF FF FF
-----------------------------------------------
VC自動在兩個bool型的成員後面新增了兩個Byte[CD CD],開始本人百思不得其解,在MSDN中也沒有找到有關此的內容,後來猜想是否在VC中定義結構其長度會補齊為4Byte的整數以適應32Bit的操作?於是我又進行了兩個測試
1:首先將將bool 型改為short 型,定義改為
typedef struct tagDef_Param
{
char Name[64];
short Need;
short NeedBuf;
int Type;
}DEF_PARAM, *PRT_DEF_PARAM;
得到的結果是正確的72
2:然後又將char 型的Name[64]陣列該為Name[10],定義改為
typedef struct tagDef_Param
{
char Name[10];
short Need;
short NeedBuf;
int Type;
}DEF_PARAM, *PRT_DEF_PARAM;
得到結果果然又不對了,應該是18Byte(144Bit),而實際結果是20Byte(160Bit)!
結論:
不知這是個的還是MSDN中有案可查屬於技術規定,但這種情況確實會給我們設計系統帶來了麻煩,特別是不同語言寫的程式碼之間傳送資料時(透過檔案或)很容易造成問題,而且非常不好查詢問題的出處。所以提醒大家在VC中定義用於資料的型別時總長度一定要定義成4Byte(32Bit)的倍數。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992812/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- VC++ 6.0的安裝及使用C++
- Salt Highstate資料結構定義資料結構
- 將go的結構定義轉化為markdown 表格(幫助快速生產文件)Go
- 建構函式定義的隱式型別轉換函式型別
- 更新win10系統後VC++ 6.0無法執行如何解決Win10C++
- 認真一點學 Go:12. 自定義型別和結構體 - 定義Go型別結構體
- EXPLAIN結果含義(轉)AI
- 分享一個無需定義結構體解析json的包結構體JSON
- libev中ev_loop結構體中巨集定義的理解OOP結構體
- 萬維考試系統檢測不到VC++ 6.0環境解決辦法C++
- Golang自定義結構體轉map 第二個人的思路Golang結構體
- PHP 陣列轉樹結構/樹結構轉陣列PHP陣列
- SAP PM 初級系列4 - 定義功能位置的結構標識
- Random 專案總結 -12 定義定時器,繫結事件random定時器事件
- 在.NET 6.0中自定義介面路由路由
- 定義運營系統架構架構
- 資料結構筆記——二叉樹的定義和性質資料結構筆記二叉樹
- 各種相關的圖結構-定義及相關研究進展
- Java中常見方法詳解合集(方法的定義及語法結構)Java
- 如何定義一個自帶資料區的結構體:三種資料結構體的比較結構體資料結構
- oracle體系結構(轉)Oracle
- 從一份定義檔案詳解ELK中Logstash外掛結構
- XML Schema(XSD)詳解:定義 XML 文件結構合法性的完整指南XML
- 物聯網學習教程—定義結構體型別變數的方法結構體型別變數
- 超融合基本架構簡單定義架構
- 定製.NET 6.0的依賴注入依賴注入
- 玩轉ASP.NET 6.0框架-序言ASP.NET框架
- 自定義響應資料結構資料結構
- 定時中斷基本結構
- go-zero微服務實戰系列(三、API定義和表結構設計)Go微服務API
- 複雜系統的有界上下文和聚合結構是如何定義的?
- golang json字串轉結構體GolangJSON字串結構體
- C++ - 結構體轉cha*C++結構體
- 優秀技術人的管理陷阱(轉)
- 定製.NET 6.0的Middleware中介軟體
- 軟體定義儲存加碼資料治理 助推金融機構數字化轉型
- JavaScript 資料由駝峰結構轉下劃線結構JavaScript
- 如何轉儲B*Tree索引的分枝結構(轉)索引
- 大規模MySQL運維陷阱之基於MyCat的偽分散式架構MySql運維分散式架構