柔性数组
来源:互联网 发布:linux安全加固脚本 编辑:程序博客网 时间:2024/05/03 10:06
(1)用途:满足需要变长度的结构体;
(2)用法:在一个结构体的最后,申明一个长度为0的数组,就可以使得这个结构体是可变长的。对编译器来说,此时的长度为0的数组并不占用空间(因为数组名本身不占空间,它只是一个偏移量。)数组名这个符号本身代表了一个不可以修改的地址常量(数组名永远不可能是指针)但对于这个数组的大小,我们可以进行动态分配。
对于0长数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包等等:
Struct Buffer
{
Int len;
Char cData[0];
};
这样的变长数组常用于网络通信中构造不定长数据包,不会浪费空间浪费网络流量,比如我要发送1024字节的数据,如果用定长包,假设定长包的长度为2048,就会浪费1024个字节的空间,也会造成不必要的流量浪费
Struct packet
{
char data[2048];
}
packet p;
memcpy(p.data,"1024 datas.........",1024)
send(socket,(char*)&p,sizeof(p));
由于考虑到数据的溢出,变长数据包中的data数组长度一般会设置得足够长足以容纳最大的数据,因此packet中的data数组很多情况下都没有填满数据,因此造成了浪费,而如果我们用变长数组来进行封包的话,就不会造成浪费(最多会造成4个字节的浪费,包头的int型的len不属于数据因此算是浪费),如前面的Buffer结构体,假如我们要发送1024个字节,我们如何构造这个数据包呢:
char *tmp = (char*)malloc(sizeof(Buffer)+1024) //这句代码的作用是申请一块连续的内存空间,这块内存空间的长度是Buffer的大小加上1024数据的大小,由两部分构成,sizeof(Buffer)和1024,如果仔细观察的话,会发现这种申请方法比第一种多了一段sizeof(Buffer)大小的空间,原因何在?如下
Buffer *p = (Buffer*)tmp;
p->len = 1024;
memcpy(p.cData,"1024 datas............",1024);
如上三行代码,首先做一个强制类型转换,Buffer类型的指针指向内存的起始位置,这段内存要分两部分使用,前部分4个字节p->len,作为包头(就是多出来的那部分),这个包头是用来描述紧接着包头后面的数据部分的长度,这里是1024,所以前四个字节赋值为1024(既然我们要构造不定长数据包,那么这个包到底有多长呢,因此,我们就必须通过一个变量来表明这个数据包的长度,这就是len的作用),而紧接其后的内存是真正的数据部分,通过p->cData定位到该部分的起始地址,最后,进行一个memcpy()内存拷贝,把要发送的数据填入到这段内存当中,最后:
send(socket,p,sizeof(Buffer)+1024);发送数据
- 柔性数组
- 柔性数组!
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- 柔性数组
- JavaScript基础之高阶函数
- 阿里云Maven仓库地址+CentOS阿里云yum源
- Hibernate学习之相关概念
- 什么是分布式系统中的幂等性
- Smart and Efficient Byte-Range Caching with NGINX & NGINX Plus
- 柔性数组
- java基础之HashMap
- git删除历史二进制文件
- 剑指offer——39.平衡二叉树
- 从Linux程序中执行shell(程序、脚本)并获得输出结果(转)
- html之初识标签
- Vmware下,从Linux系统安装到yum源配置(包括Centos7.X、Rhel7.X)
- Java中private、protected、public和default修饰符的访问限制
- 基于dalvik模式下的Xposed Hook开发的某加固脱壳工具