VC++ 6.0 结构定义大陷阱

原创 2002年08月15日 09:19:00

VC++ 6.0 结构定义大陷阱!!!

本人写一个程序,定义一个参数类型
typedef struct tagDef_Param
{
 char Name[64];
 bool Need;
 bool NeedBuf;
 int Type;
}DEF_PARAM, *PRT_DEF_PARAM;

为了方便,所用的参数内容通过Excel来维护,并通过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;
 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)!

结论:
不知这是个微软的Bug还是MSDN中有案可查属于技术规定,但这种情况确实会给我们设计系统带来了麻烦,特别是不同语言写的代码之间传送数据时(通过文件或网络)很容易造成问题,而且非常不好查找问题的出处。所以提醒大家在VC中定义用于交换数据的类型时总长度一定要定义成4Byte(32Bit)的倍数。

C++中cout和printf在vc6.0中的区别

printf :  c语言中产生格式化输出的函数(定义在 stdio.h 中)。向终端输出(显示器、控制台等) cout: C++中的标准输出流。 首先请看下边一段代码: #inclu...
  • u012619920
  • u012619920
  • 2013年12月08日 11:04
  • 546

VC++中结构体的定义及使用

结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。结构体最最主要的意义就是封装,而封装的好处就是可以再次利用。掌握了结构体的定义和使用方法,对编程具有非常重要的意义...
  • margin1988
  • margin1988
  • 2013年10月16日 15:13
  • 3370

大败局I,多元化是个陷阱吗?

至于多元化,研究这方面的书籍已经多如牛毛,具体内容还是有需要看看那些书吧。 按理说如今国内市场大都已经趋向于专业化阶段,但是由于饿了么,滴滴的兴起,互联网+带动了一批批所谓的蓝海,引得一批批壮志青...
  • a969323511
  • a969323511
  • 2017年02月21日 23:41
  • 169

Installshield for VC++ 6.0

Installshield for VC++ 6.0搜便了整个世界,就csdn下载到了不过要11分,还分两份晕,呵呵自己重新上传了一个http://download.csdn.net/source/1...
  • yangzhenping
  • yangzhenping
  • 2009年10月07日 00:17
  • 2112

[教程]VC++6.0的简单使用

鉴于许多同学的vc++6.0无法正常使用,并且不会创建工程及文件,还有的同学会遇到一些编译的问题,我在这里做个小教程 1.工具的准备 首先,我把需要的资源给大家。一共就两个文件,一个安装文...
  • zkx981105
  • zkx981105
  • 2017年12月04日 11:18
  • 352

VC++ 学习笔记(12)——VC6.0 程序打包

VC6.0将程序打包成一个可执行文件(release)(1)控制台应用程序首先打开程序,工程(Project)->设置(Settings...),左侧Settings For下拉列表选择Win32 R...
  • valerie_7
  • valerie_7
  • 2011年01月14日 16:31
  • 3665

vc OnInitialUpdate的应用

      视图窗口完全建立后第一个被框架调用的函数。框架在第一次调用OnDraw前会调用OnInitialUpdate,因此OnInitialUpdate是设置滚动视图的逻辑尺寸和映射模式的最合适的...
  • iiilden
  • iiilden
  • 2010年04月01日 12:32
  • 841

VC++ 线程池

 服务器程序利用线程技术响应客户请求已经司空见惯,可能您认为这样做效率已经很高,但您有没有想过优化一下使用线程的方法。该文章将向您介绍服务器程序如何利用线程池来优化性能并提供一个简单的线程池实现。线程...
  • aa211314
  • aa211314
  • 2008年02月28日 16:27
  • 8163

【转】vc++6.0 字节定义和字节转换。

一、定义 在VC6.0的Microsoft Visual Studio/VC98/Include/windef.h 里,定义了BYTE,WORD,DWORD typedef unsigned lo...
  • caozhenyu
  • caozhenyu
  • 2015年06月07日 23:53
  • 1409

VC++ 6.0

VC++ 6.0实用技巧汇总   1.检测程序中的括号是否匹配 把光标移动到需要检测的括号(如大括号{}、方括号[]、圆括号()和尖括号   2:定位预处...
  • in_han
  • in_han
  • 2013年04月02日 14:42
  • 486
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC++ 6.0 结构定义大陷阱
举报原因:
原因补充:

(最多只允许输入30个字)