头条资讯网_今日热点_娱乐才是你关心的时事新闻

今日热点 时事资讯
娱乐头条才是你关心的新闻
首页 > 头条资讯 > 科技

为什么有些结构体中会定义一个字节的数组

有一些Windows结构体是可变长度的,它们通常会有一个固定长度的头部,然后接下来是一个可变长度的数组。当这些结构体被声明的时候,它们通常会被声明为一个只有一个字节元素的数组,如下图所示:

如果我们观察一下头文件中的定义,就会发现,这里的ANYSIZE_ARRAY被定义成了1,也就是说,这个结构体的结尾是一个只包含1个字节的数组。

通过这样的声明,我们可以分配一个可变长度的结构体,如下图所示:

然后,我们可以通过下图所示的方式来对结构体进行初始化:

有一些开发者可能会认为这个结构体应该像下图这样定义:

然后,结构体的内存分配就看起来像下图这样进行:

这样的做法,会有两个缺陷:一个表面上可见的缺陷,和一个致命缺陷,容我慢慢道来。

首先,这样的设计,会导致客户非常难以访问一个可变长度的数据,对TOKEN_GROUPS结构体的初始化可能如下图这样进行:

真正的缺陷在于,上述代码会在一台64位Windows系统上崩溃,下面是SID_AND_ATTRIBUTES结构体的定义:

上述的结构体定义中,第一个成员是一个PSID指针。SID_AND_ATTRIBUTES结构体需要指针对齐,而在一台64位的Windows系统上是8字节对齐的。另一方面,TOKEN_GROUPS结构仅仅包含一个DWORD,因此它仅需要在4字节边界上对齐,而sizeof(TOKEN_GROUPS)的值为4。

我希望你能看出来现在是什么样一个状况。

从底层结构上来看,SID_AND_ATTRIBUTES结构不会对齐到一个8字节的边界,而是会对齐到4个字节边界,而用来填充这中间的间隙的部分被忽视了。所以,当尝试访问这个数组的成员的时候,会直接导致一个

STATUS_DATATYPE_MISALIGNMENT异常。

你可能会问了,那为什么不使用一个长度为0的数组,而使用1个字节的数组呢?

因为:”时间旅行目前还只是一个幻想而已。”

在1999年之前,标准C语言还不支持一个长度为0的数组。而Windows的开发远远早于这个时间点,因而不大可能会利用这个语言特性。

总结

可变长度的数据结构,在网络数据传输中颇有用处。

我为啥知道?兄弟我吃过这方面的亏。

最后

RaymondChen的《TheOldNewThing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。

本文来自:《Whydosomestructuresendwithanarrayofsize1?》

最近我写了个东西

正如你们所知道的,拓扑梅尔智慧办公平台(TopomelBox)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。

我想:你值得拥有。

未经允许不得转载:头条资讯网_今日热点_娱乐才是你关心的时事新闻 » 为什么有些结构体中会定义一个字节的数组

分享到:更多 ()
来源:漫漫开发路 编辑:科技

评论

留言/评论 共有条点评
昵称:
验证码:
匿名发表