在一些 C 语言编写的代码中,有时可以看到如下定义的结构:
view plaincopy to clipboardprint?
1. typedef struct user_def
2. {
3. char * name;
4. int length;
5. char bytes[0];
6. } user_def_t;
typedef struct user_def { char * name; int length; char bytes[0]; } user_def_t;
这个 bytes 是什么意思?我们知道 0 == sizeof(bytes),那么 bytes 仅仅是为了定义结构的尾地址吗?
不是的。这里的 bytes 是作为扩展数组用的。请看如下代码:
view plaincopy to clipboardprint?
1. int alloc_user_def_t(user_def_t * p, int length)
2. {
3. p = (user_def_t)malloc(sizeof(user_def_t) + length);
4. if (NULL == p)
5. {
6. return -1;
7. }
8.
9. p->name = NULL;
10. p->length = length;
11. memset(p->bytes, 0, length);
12. return 0;
13. }
int alloc_user_def_t(user_def_t * p, int length) { p = (user_def_t)malloc(sizeof(user_def_t) + length); if (NULL == p) { return -1; } p->name = NULL; p->length = length; memset(p->bytes, 0, length); return 0; }
是不是很酷?同样,也可以把 name 域的值附在结构后面:
view plaincopy to clipboardprint?
1. int alloc_user_def_t(user_def_t * p, char * name, int length)
2. {
3. p = (user_def_t)malloc(sizeof(user_def_t) + strlen(name) + length + 1);
4. if (NULL == p)
5. {
6. return -1;
7. } p->name = p + sizeof(user_def_t) + length;
8. memcpy(p->name, name, strlen(name) + 1); /* 别忘了'\0' */
9. p->length = length;
10. memset(p->bytes, 0, length);
11. return 0;
12. }
int alloc_user_def_t(user_def_t * p, char * name, int length) { p = (user_def_t)malloc(sizeof(user_def_t) + strlen(name) + length + 1); if (NULL == p) { return -1; } p->name = p + sizeof(user_def_t) + length; memcpy(p->name, name, strlen(name) + 1); /* 别忘了'\0' */ p->length = length; memset(p->bytes, 0, length); return 0; }
总结:在某一结构末尾如定义类似 char bytes[0] 的零长数组,表示该结构不定长,可通过数组的方式进行扩展。结构中必包含一个长度信息。结构本身类似于一个信息头。同时,此结构只能通过堆方式分配内存。
PS:注意在用malloc分配空间时要分配数组的空间,不然会出现溢出!
分享到:
相关推荐
结构体零长度数组的意义(深入)1
2.可以把结构体中定义了零长度数组的地方 视为结构体的结尾,在它之后最好不要再定义任何字段 4.等价写法:typedef struct user_def{
在Linux系统里,/usr/include/linux/if_pppox.h里面有这样...使用起来非常方便,创建时,malloc一段结构体大小加上可变长数据长度的空间给它,可变长部分可按数组的方式访问,释放时,直接把整个结构体free掉就可以了。
c#中结构数组的定义,很全的
最近的项目在做socket通信报文解析的时候,用到了结构体与字节数组的转换;由于客户端采用C++开发,服务端采用C#开发,所以双方必须保证各自定义结构体成员类型和长度一致才能保证报文解析的正确性,这一点非常重要...
定义自定义类型的数组时,时常出现所占字长不一致的情形,需要用此办法解决
(1)利用结构体或数组模拟网络数据包结构。 (2)编码实现CRC算法,并将得到的校验位附加到网络数据包相应的位置。 (3)根据数据包的长度,随机生成一个数据包产生突变的位置,并对该位置的bit位模拟突变的产生。 ...
今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用struct实现变长数组的技术。下面是我在网上找到的一篇讲解很...
求struct各种组合的长度,以及指针、数组、字符串的长度;
2.定义CharNums结构体数组,长度为字符串的长度 3.直接为CharNums结构体数组中的第一个元素赋值,其中字符设置为字符数组中的第一个元素,出现次数为1,并设置变量count为1 4.之后字符数组中每一个字符均与...
写在前面: 本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正...那么我们这时候如果我们用这个数组来接收串口接收信息,信息的格式是: 数据头 ->数据长度 ->数据区 ->数据校验 ->数据尾 假设数据
1)在计算机中建立有限规模的电子英汉词典(文件),本词典采用一个包含N个数据的结构体数组,每个数据的结构应当包括:英文单词、词性、拼读音标、中文(汉语拼音)。 2)对单词和释义字符串长度的限定分别为不少于...
用结构体创建一个数组,对数组进行了基本的操作,包括数组的插入、删除、排序、求长度等
可计算方差、标准差,任何合法表达试的值
如果dll文件中只包含一些基础类型,那这个问题可能可以被忽略,但是如果是组合类型(这个叫法也许不妥),如结构体、类类型等,在其中的成员变量的长度的申明正确与否将决定你对dll文件调用的成败。 如有以下代码,...
数组的每个元素都被初始化为元素类型对应的零值 数组的长度位置出现的是“...”省略号,则表示数组的长度是根据初始 化值的个数来计算,[...]int{1, 2, 3}表示[3]int{1, 2, 3} 数组的长度是数组类型的一
下面小编就为大家带来一篇C++使struct对象拥有可变大小的数组(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
% A 和 B 必须属于同一类型,并且属于以下类型之一: % 结构体、元胞数组、数值或逻辑数组或字符串。 % A 和 B 可能包含以上所列类型的其他元素(如果它们% 是元胞数组或结构)。 % 如果 A 和 B 是结构体,和/或...
true(默认)=> 每个字段数组的长度必须相同。 false => 字段数组可以有不同的长度。 OUT [Nx1] 列数组,由 N 个结构组成,具有相同的 IN 字段, 与标量值。 N 是输入的最大数组长度结构域。 较短的数组将导致空字...
项目中遇到C#调用C++算法库的情况,C++内部运算结果返回矩形坐标数组(事先长度未知且不可预计),下面方法适用于访问C++内部分配的任何结构体类型数组。当时想当然的用ref array[]传递参数,能计算能分配,但是在C#...