变长结构体

 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. frp 使用入门

    1.下载安装对应系统版本 https://github.com/fatedier/frp/releases/ 2.将下载的frp移动到系统软件目录 mv frp/ /usr/local 3.配置frp ...

  2. make command explaination 編譯命令解釋

    Creating .config file make ARCH=arm CROSS_COMPILE=arm-none-eabi- stm32_defconfig 以上命令是 將變數 ARCH=arm, ...

  3. Android IPC

    1. 什么是Android IPC IPC:inter-process Commnication跨进程的通信,多进程之间的通信,不同的操作系统有不同的通信方式,Android继承自Linux,但其IP ...

  4. caffe Python API 之激活函数ReLU

    import sys import os sys.path.append("/projects/caffe-ssd/python") import caffe net = caff ...

  5. 苹果电脑Mac OS系统重装图文详解

    苹果电脑Mac OS系统重装图文详解 本文来自于[系统之家] www.xp85.com现在电脑都很强大,可是也很脆弱,常常需要你去维护,甚至经常需要你重装系统,那么Mac OS又如何重装系统呢?刚刚使 ...

  6. Django Rest Framework用户访问频率限制

    一. REST framework的请求生命周期 基于rest-framework的请求处理,与常规的url配置不同,通常一个django的url请求对应一个视图函数,在使用rest-framewor ...

  7. %和format的区别

    在python中字符串的格式化分为两种:%和format.那么我们在什么时候来使用它们呢?它们有什么区别呢? 举个例子:我们根据一个坐标来表示一个动作 #定义一个坐标 point = (250,250 ...

  8. Convert Sorted List to Binary Search Tree&&Convert Sorted Array to Binary Search Tree——暴力解法

    Convert Sorted List to Binary Search Tree Given a singly linked list where elements are sorted in as ...

  9. 前端读者 | Javascript设计模式理论与实战:状态模式

    本文来自 @狼狼的蓝胖子:链接:http://luopq.com/2015/11/25/design-pattern-state/ 在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将 ...

  10. QT库在Windows上的编译

    1.从http://www.qtcentre.org/下载QT源代码,注意是源代码.我下载到的是QT4.5.1版,文件名为qt-win-opensource-src-4.5.1.zip: 2.解压,注 ...