struct MyData 
{
    int nLen;
    char data[0];
};

在结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。

这表明data没有占用空间。data是一个数组名;该数组没有元素;该数组的真实地址紧随结构体Info之后;这种声明方法可以巧妙的实现C语言里的数组扩展。

实际用时采取这样:
         struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))
         这样就可以通过p->data 来操作这个str。

示例:
#include <iostream>

using namespace std;

struct MyData 
{
    int nLen;
    char data[0];
};

int main()
{
    int nLen = 10;
    char str[10] = "123456789";

cout << "Size of MyData: " << sizeof(MyData) << endl;

MyData *myData = (MyData*)malloc(sizeof(MyData) + 10);
    memcpy(myData->data,  str, 10);

cout << "myData's Data is: " << myData->data << endl;

free(myData);

return 0;
}
         输出:
Size of MyData: 4
myData's Data is: 123456789

C99标准为了让这种用法合法化,专门定义了flexible array member,直接就是
struct Name { int size, char foo[] }; 不再写 char foo[0] 了。

它只能放在结构体末尾, 
是申明一个长度为0的数组(eg. char data[0] ;或 int data[0];都行) 
可以使得这个结构体是可变长的。

引申:

 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <iostream>
 using namespace std;
 typedef struct test0{
     ];
     int b;
     char c;
 }sttest0;
 typedef struct test{
     ];
     ];
 }sttest;
 typedef struct test1{
     ];
     ];
 }sttest1;
 typedef struct test2{
     struct test tt;
     struct test1 tt1;
 }sttest2;

 int main()
 {
     ] = ";
     int len1 = sizeof(str);
     cout << len1 << endl;
     ] ="abcdefghij";
     int len2=sizeof(str2);
     cout << len2 << endl;
     printf("%lu %lu %lu\n", sizeof(sttest0), sizeof(sttest), sizeof(sttest1));
     cout << "Size of sttest2: " << sizeof(sttest2) << endl;
     sttest2 *tt2 = (sttest2*));

     memcpy(tt2->tt.a, str, len1);
     memcpy(tt2->tt1.a , str2, len2);

     //需要注意的是两者位置互换后的情况
 //    memcpy(tt2->tt1.a , str2, len2);
 //    memcpy(tt2->tt.a, str, len1);

     printf("#################value\n");
     printf("tt:%s\n%s\n", tt2->tt.a, tt2->tt.b);
     printf("tt1:%s\n%s\n", tt2->tt1.a, tt2->tt1.b);

     printf("#################address\n");
     printf("addr(tt2):%#x\n%#x\n", &tt2->tt, &tt2->tt1);
     printf("addr(tt):%#x\n%#x\n", &tt2->tt.a, &tt2->tt.b);
     printf("addr(tt1):%#x\n%#x\n", &tt2->tt1.a, &tt2->tt1.b);
     free(tt2);
     ;
 }

柔性数组 data[0]的更多相关文章

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

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

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

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

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

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

  4. c99柔性数组

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

  5. C/C++ 中的0长数组(柔性数组)

    转自C/C++ 中的0长数组(柔性数组) 在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的.但是,GUN中却允许使用,而且,很多时候,应用在了 ...

  6. C语言0长度数组(柔性数组)

    0长度数组,又称为柔性数组(flexible array).通经常使用来实现变长数组.常见于TLV(type-length-value)的数据结构中. 在标准 C 和 C++ 中,不同意用 0 长度数 ...

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

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

  8. (四)C语言柔性数组、指针赋值

    一.柔性数组 今天看了公司的代码,发现一个很奇怪的问题,后来自己写了类似代码,我先把代码贴出来吧. #include<stdio.h> #include<string.h> # ...

  9. C柔性数组

    柔性数组成员 柔性数组 .允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内存. .包含柔性数组成员的结构要使用malloc()函数进行内存的动态分配.分配的内存大于结 ...

随机推荐

  1. java之stream(jdk8)

    一.stream介绍 参考: Java 8 中的 Streams API 详解   Package java.util.stream   Java8初体验(二)Stream语法详解   二.例子 im ...

  2. am335x sd卡启动系统参数设置

    首先直接记录结果 在u-boot 中修改参数 #define AUTO_UPDATESYS */ 直接把这个参数注释掉. 这个参数是原来用来升级nor flash 启动系统设置的一个参数,也就是说, ...

  3. 装b指南

    提溜一个糖水黄桃罐头瓶,放在桌边,坐下以后,脖子略微后仰,翘着二郎腿,低头盯着屏幕看需求. 最好点一根烟,牌子无所谓,能冒烟就行.要得就是云山雾绕的感觉,从烟雾中眯着眼睛看出去,一副胸有成竹的样. 一 ...

  4. Windows 2008R2关闭网络发现

    在Windows Server 2008 R2安装完后,默认情况下,在高级共享设置中无法对网络发现的更改进行保存(每次选择"启用网络发现"后保存修改,但重新打开"高级共享 ...

  5. NOIP 2010题解

    唔..NOIP2010比较简单,总体感觉不错. Problem 1: 机器翻译 水题,队列的简单应用. 读入时判断是否在内存中,可以用hash优化.如果不在内存中push进内存,放不下了pop hea ...

  6. mkdir:批量创建文件夹

    问题:mkdir dir[0-9]创建文件夹时,并没有如预期创建dir0~dir9这几个文件夹,而是创建了dir[0-9]这一个文件夹. 网上看了些相关资料,发现以前对[0-9]的理解不够透彻: &q ...

  7. 如何用js控件div的滚动条,让它在内容更新时自动滚到底部?

    三种控制DIV内容滚动的方法: 方法一:使用锚标记要滚动到的位置,然后通过click方法模拟点击滚动到锚所在位置 <script language="javascript1.2&quo ...

  8. espcms列表页ajax获取内容 - 并初始化swiper

    <link rel="stylesheet" href="swiper.min.css" type="text/css" media= ...

  9. How to keep Environment Variables when Using SUDO

    The trick is to add environment variables to sudoers file via sudo visudo command and add these line ...

  10. Repository设计模式

    definition: 通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调. advantage: 使用该模式的最大好处就是将领域模型从客户代码和数据映射层之间解耦出来. 理解内 ...