admin管理员组文章数量:1638924
最近看别人的代码,发现中间有这样的使用:
tmp->FileName[i];
其中tmp是一个指针,指针类型是FILE_NOTIFY_INFORMATION *的。而FILE_NOTIFY_INFORMATION 的定义是这样的:
typedef struct _FILE_NOTIFY_INFORMATION {
DWORD NextEntryOffset;
DWORD Action;
DWORD FileNameLength;
WCHAR FileName[1];
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;
可以看到,FileName是一个固定大小字符数组,他的大小是1,开头的tmp->FileName[i];中的i是大于1的,为什么使用起来不会崩溃呢?
原来这和tmp的定义方式有关。
char notify[1024];
FILE_NOTIFY_INFORMATION *tmp=(FILE_NOTIFY_INFORMATION *)notify;
然后对tmp进行填充,如果填充后的长度大于了FILE_NOTIFY_INFORMATION的长度,那么就是说FileName的实际可引用的范围就变大了。为什么呢?
因为tmp不是一个FILE_NOTIFY_INFORMATION 结构,而是指针的方式,它是将一段已经分配好的内存强制转换成FILE_NOTIFY_INFORMATION *格式的,由于最后一个成员的定义是字符数组,而字符数组的规矩是遇到零字符结束,所以只要FileName[0]和后面紧跟的字符不是非零字符,他的引用就不会结束,直到遇到零字符。
但是这也不是没有限制的,FileName的引用大小不可以超过1024 - 3 * dword的大小,否则就会越界了。
C99 柔性数组结构成员
- 结构体变长的妙用——0个元素的数组
有时我们需要产生一个结构体,实现了一种可变长度的结构。如何来实现呢?
看这个结构体的定义:
typedef struct st_type
{
int nCnt;
int item[0];
}type_a;
(有些编译器会报错无法编译可以改成:)
typedef struct st_type
{
int nCnt;
int item[];
}type_a;
这样我们就可以定义一个可变长的结构,用sizeof(type_a)得到的只有4,就是sizeof(nCnt)=sizeof(int)那 个0个元素的数组没有占用空间,而后我们可以进行变长操作了。
C语言版:
type_a *p = (type_a*)malloc(sizeof(type_a) + 100*sizeof(int));
C++语言版:
type_a *p = (type_a*)new char[sizeof(type_a) + 100*sizeof(int)];
这样我们就产生了一个长为100的type_a类型的东西用p->item[n]就能简单地访问可变长元素,原理十分简单 ,分配了比sizeof(type_a)多的内存后int item[];就有了其意义了,它指向的是int nCnt;后面的内容,是没 有内存需要的,而在分配时多分配的内存就可以由其来操控,是个十分好用的技巧。
而释放同样简单:
C语言版:
free(p);
C++ 语言版:
delete []p;
其实这个叫灵活数组成员(fleible array member)C89不支持这种东西,C99把它作为一种特例加入了标准。但 是,C99所支持的是incomplete type,而不是zero array,形同int item[0];这种形式是非法的,C99支持的 形式是形同int item[];只不过有些编译器把int item[0];作为非标准扩展来支持,而且在C99发布之前已经有 了这种非标准扩展了,C99发布之后,有些编译器把两者合而为一。
本文标签: 柔性数组使用说明FILENOTIFYINFORMATION
版权声明:本文标题:柔性数组---FILE_NOTIFY_INFORMATION的使用说明 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729280156a1193962.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论