变长结构体

 struct test
{
int nSize;
char data[]; // 或者 char data[0];但建议使用 char data[]; 注意:c98 时不支持柔性数组,其仅作为非标准扩展。到c99时纳入标准
};

如上面代码即为一变长结构体,其中 char data[]; 为一变长数组,称之为柔性数组。正是因其为变长数组,故结构体才可变长。使用 test 结构体时,可用 malloc 申请大于 sizeof(test) 长度的空间。如下:

     const auto nSizeTest    = sizeof(test);
const auto nExtraSize = * (sizeof(char)); test* stpTest = (test*)malloc(nSizeTest + nExtraSize); stpTest->nSize = nSizeTest + nExtraSize;
memset((void*)stpTest->data, 0x0L, nExtraSize);
const auto nTempLen = strlen(stpTest->data);
for (auto nIndex = ; nIndex < nExtraSize - ; ++nIndex) {
stpTest->data[nIndex] = char( + nIndex);
}
stpTest->data[nExtraSize - ] = '\0'; // some code here........ free(stpTest); // 此处 free 的是刚才所申请的全部内存空间
stpTest = nullptr;

使用柔性数组有以下几个好处:

  • 首先柔性数组不占内存,值代表地址;
  • 可以通过stpTest->data来访问字符串,符合常规用法。
  • 字符串长度为动态分配。

关于柔性数组的注意点:

  1. 柔性数组只能放置于结构体的末尾声明
  2. 由于柔性数组是动态可变长的,则一般情况下只会用在没有继承关系、没有虚表的变长结构体(或类中)中,如果有继承关系的或虚表,则后果将非常严重。(有看过对象模型的人,肯定清楚为什么,此处就不多说)
  3. 上面变长结构体中的柔性数组除了 char 型别外,还可以是其他任何类型,甚至是自定义的类类型。但是:如果是自定义的类类型,则需要自己手动调用构造与析构。因为 malloc 与 free 时,不会自动调用构造与析构。从而可能导致不可预知的结果,以及内存泄漏的可能。比如:
 class obj
{
public:
int nIndex;
~obj() {
std::cout << "obj " << nIndex << " destroy" << std::endl;
}
}; struct test
{
int nSize;
obj data[];
}; int _tmain(int argc, _TCHAR* argv[])
{ const auto nSizeTest = sizeof(test);
const auto nExtraSize = * (sizeof(obj)); test* stpTest = (test*)malloc(nSizeTest + nExtraSize); stpTest->nSize = nSizeTest + nExtraSize;
memset((void*)stpTest->data, 0x0L, nExtraSize);
for (auto nIndex = ; nIndex < ; ++nIndex) {
stpTest->data[nIndex].nIndex = nIndex + ;
} auto nSize = sizeof(test);
std::cout << "sizeof(test) = " << nSize << std::endl; // 此处输出 4.说明柔性数组并不会占用 test 的空间. nSize = sizeof(*stpTest);
std::cout << "sizeof(*stpTest) = " << nSize << std::endl; // 此处输出 4 obj* ptr = stpTest->data; free(stpTest); // 此处将释放前面所申请的全部空间,但是:不会调用 ~obj() 函数!!!
stpTest = nullptr; //ptr->nIndex = 777; // 如果调用此句会蹦,因为前面 free 时已经全部释放掉所申请空间了,包括柔性数组 data 的那3个 obj 对象的空间 system("pause"); return ;
}

参考文献:

c99柔性数组的更多相关文章

  1. C99标准的柔性数组 (Flexible Array)

    [什么是柔性数组(Fliexible Array)] 柔性数组在C99中的定义是: 6.7.2.1 Structure and union specifiers As a special case, ...

  2. C语言柔性数组

    结构中最后一个元素允许是未知大小的数组,这个数组就是柔性数组.但结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内 ...

  3. 柔性数组-读《深度探索C++对象模型》有感 (转载)

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  4. 柔性数组-读《深度探索C++对象模型》有感

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  5. C语言柔性数组讲解

    #include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ; ...

  6. flexible array柔性数组、不定长的数据结构Struct详解

    柔性数组,这个名词对我来说算是比较新颖的,在学习跳跃表的实现时看到的.这么好听的名字,的背后到底是如何的优雅. 柔性数组,其名称的独特和迷惑之处在于“柔性”这个词.在C/C++中定义数组,是一个定长的 ...

  7. C柔性数组

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

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

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

  9. 柔性数组成员 (flexible array member)-C99-ZZ

    学习flexible array member是因为阅读Redis源码遇到的,sds.h中一开始就用到了. ============================================== ...

随机推荐

  1. js中的for in 循环

    1.数组 使用for in 遍历数组时,其索引被视为对象的属性,从而直接输出数组的索引 var arr = ["a","b","c"]; f ...

  2. CreateProcess中的部分参数理解

    函数原型,这里写Unicode版本 WINBASEAPIBOOLWINAPICreateProcessW( _In_opt_ LPCWSTR lpApplicationName, //可执行文件名字 ...

  3. 网络设备之net_device结构与操作

    net_device结构是一个很大的结构,其中包含了硬件信息,接口信息,其他辅助信息,以及设备操作函数等: 目前仍在读代码中,后续字段注释会逐渐补充: /** * struct net_device ...

  4. lsb_release查看当前系统的发行版信息

    Linux除了用uname -r查看系统版本信息外,还可以用lsb_release. 安装: yum install -y redhat-lsb-core 使用: lsb_release -a

  5. HTML5API(2)

    四.文件API 1.概述 H5允许JS有条件的读取客户端文件 允许读取的文件:1.待上传的文件2.拖进浏览器的文件 多文件上传设置属性multiple 过滤上传文件类型 设置accept属性 acce ...

  6. Mysql 数据库学习笔记02 编程

    一.常量 * 字符串常量 * 数值常量 * 十六进制常量 * 日期时间常量 * 位字段常量 * 布尔值 * NULL值 二.变量 * 用户变量:用户自定义变量: * 系统变量:系统内部定义的变量: 1 ...

  7. ZOJ-3318

    Strange Country Time Limit: 1 Second      Memory Limit: 32768 KB There are n cities in the dream cou ...

  8. Palindrome Partitioning——回溯算法的又一经典

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  9. 探索sklearn | 鸢尾花数据集

    1 鸢尾花数据集背景 鸢尾花数据集是原则20世纪30年代的经典数据集.它是用统计进行分类的鼻祖. sklearn包不仅囊括很多机器学习的算法,也自带了许多经典的数据集,鸢尾花数据集就是其中之一. 导入 ...

  10. Mvc全局过滤器与Action排除

    http://blog.csdn.net/shuaihj/article/details/53020428 如何一次性给所有action做登录验证过滤,如何排除不需要做登录验证的action? 1. ...