转自:http://blog.csdn.net/yby4769250/article/details/7294696

在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的。

但是,GUN中却允许使用,而且,很多时候,应用在了变长结构体中,如:

struct Packet
{
int state;
int len;
char cData[0]; //这里的0长结构体就为变长结构体提供了非常好的支持
};

首先对0长数组做一个解释:

用途 :长度为0的数组的主要用途是为了满足需要变长度的结构体。

用法 :在一个结构体的最后 ,申明一个长度为0的数组,就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量(注意:数组名永远都不会是指针!),但对于这个数组的大小,我们可以进行动态分配。

请仔细理解后半部分,对于编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,代表一个不可修改的地址常量!

对于0长数组的这个特点,很容易构造出变长结构体,如缓冲区,数据包等等:

struct Buffer
{
int len;
char cData[0];
};

这样的变长数组常用于网络通信中构造不定长数据包,不会浪费空间浪费网络流量,比如我要发送1024字节的数据,如果用定长包,假设定长包的长度为2048,就会浪费1024个字节的空间,也会造成不必要的流量浪费

struct packet
{
char data[2048];
}
packet p;
memcpy(p.data,"1024 data.........",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 data............",1024);

如上三行代码,首先做一个强制类型转换,Buffer类型的指针指向内存的起始位置,这段内存要分两部分使用,前部分4个字节p->len,作为包头(就是多出来的那部分),这个包头是用来描述紧接着包头后面的数据部分的长度,这里是1024,所以前四个字节赋值为1024(既然我们要构造不定长数据包,那么这个包到底有多长呢,因此,我们就必须通过一个变量来表明这个数据包的长度,这就是len的作用),而紧接其后的内存是真正的数据部分,通过p->cData定位到该部分的起始地址,最后,进行一个memcpy()内存拷贝,把要发送的数据填入到这段内存当中,最后:

send(socket,p,sizeof(Buffer)+1024);//发送数据

[C/C++] char data[0](柔性数组)的更多相关文章

  1. C语言变长数组 struct中char data[0]的用法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用s ...

  2. 【转】char data[0]用法总结

    @2019-07-31 struct MyData { int nLen; ]; }; 开始没有理解红色部分的内容,上网搜索下,发现用处很大,记录下来. 在结构中,data是一个数组名:但该数组没有元 ...

  3. 柔性数组 data[0]

    struct MyData {    int nLen;    char data[0];}; 在结构中,data是一个数组名:但该数组没有元素:该数组的真实地址紧随结构体MyData之后,而这个地址 ...

  4. C语言变长数组data[0]

    1.前言 在刷题时遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data[0] ...

  5. C语言变长数组data[0]【总结】

    1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data ...

  6. C语言变长数组data[0]总结

    C语言变长数组data[0] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内 ...

  7. c99柔性数组

    变长结构体 struct test { int nSize; char data[]; // 或者 char data[0];但建议使用 char data[]; 注意:c98 时不支持柔性数组,其仅 ...

  8. C语言的柔性数组的实现及应用

    c编程的时候数组长度一般都是固定好的,实际上c还能实现变长数组.其实c99中确实是有变长数组的说法,C99中通过允许结构体中的最后一个成员是长度未知的数组实现变长数组,其定义格式如下: typedef ...

  9. GNU C的定义长度为0的数组

    在标准C和C++中,长度为0的数组是被禁止使用的.不过在GNU C中,存在一个非常奇怪的用法,那就是长度为0的数组,比如Array[0];很多人可能觉得不可思议,长度为0的数组是没有什么意义的,不过在 ...

随机推荐

  1. Old ST-LINK firmware detected.do you want to upgrade it?已解决,stlink升级

    错误提示: 原因: stlink固件太旧了, 解决办法: 升级stlink固件,升级方法: 1. 下载st link utility工具. 官网下载:https://www.st.com/conten ...

  2. STL---llist

    #include<iostream> #include<algorithm> #include<list> using namespace std; struct ...

  3. go内建容器-Map

    1.基础定义 golang中的map如同它的函数一样"纯粹",map就是用来存储键值对的容器,别管什么哈希不哈希的(底层已实现),用就行 //创建一个map m := map[st ...

  4. Uber优步北京第四组奖励政策

    优步北京第四组: 定义为2015年7月20日至今激活的司机(以优步后台数据显示为准) 滴滴快车单单2.5倍,注册地址:http://www.udache.com/如何注册Uber司机(全国版最新最详细 ...

  5. 青岛Uber优步司机奖励政策(1月4日~1月10日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  6. VINS(六)边缘化

    通常的边缘化是将联合概率分布分解为边缘概率分布和条件概率分布的过程,这样可以将Sliding Window中较旧的状态边缘化出Sliding Window,同时保留其信息.并且保证了对应H海塞矩阵的稀 ...

  7. SpringBoot 基于lettuce 连接池 配置redis多数据源操作 生产配置

    添加pom<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons- ...

  8. spring data jap操作

    package com.example.demo; import com.example.entity.UserJ; import com.example.respository.UserJRespo ...

  9. wamp报错SCREAM:Error suppression ignored for

    问题:SCREAM:Error suppression ignored for 解决: 在php.ini最下面加入scream.enabled = Off http://stackoverflow.c ...

  10. leetcode-组合总数IV(动态规划)

    377. 组合总和 Ⅳ 给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数. 示例: nums = [1, 2, 3] target = 4   所有可能的组合为: (1, ...