c99柔性数组
变长结构体
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来访问字符串,符合常规用法。
- 字符串长度为动态分配。
关于柔性数组的注意点:
- 柔性数组只能放置于结构体的末尾声明
- 由于柔性数组是动态可变长的,则一般情况下只会用在没有继承关系、没有虚表的变长结构体(或类中)中,如果有继承关系的或虚表,则后果将非常严重。(有看过对象模型的人,肯定清楚为什么,此处就不多说)
- 上面变长结构体中的柔性数组除了 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柔性数组的更多相关文章
- C99标准的柔性数组 (Flexible Array)
[什么是柔性数组(Fliexible Array)] 柔性数组在C99中的定义是: 6.7.2.1 Structure and union specifiers As a special case, ...
- C语言柔性数组
结构中最后一个元素允许是未知大小的数组,这个数组就是柔性数组.但结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内 ...
- 柔性数组-读《深度探索C++对象模型》有感 (转载)
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- 柔性数组-读《深度探索C++对象模型》有感
最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...
- C语言柔性数组讲解
#include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ; ...
- flexible array柔性数组、不定长的数据结构Struct详解
柔性数组,这个名词对我来说算是比较新颖的,在学习跳跃表的实现时看到的.这么好听的名字,的背后到底是如何的优雅. 柔性数组,其名称的独特和迷惑之处在于“柔性”这个词.在C/C++中定义数组,是一个定长的 ...
- C柔性数组
柔性数组成员 柔性数组 .允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内存. .包含柔性数组成员的结构要使用malloc()函数进行内存的动态分配.分配的内存大于结 ...
- C语言0长度数组(柔性数组)
0长度数组,又称为柔性数组(flexible array).通经常使用来实现变长数组.常见于TLV(type-length-value)的数据结构中. 在标准 C 和 C++ 中,不同意用 0 长度数 ...
- 柔性数组成员 (flexible array member)-C99-ZZ
学习flexible array member是因为阅读Redis源码遇到的,sds.h中一开始就用到了. ============================================== ...
随机推荐
- Centos7的iso everything与DVD以及Live的区别
DVD.ISO 可以用安装程序安装的所有安装包,推荐镜像 Netinstall.iso 从网络安装或者救援系统 Everything.iso 包含centos7的一套完整的软件包,可以用来安装系统或者 ...
- pdf文件添加到word中
今天遇到了一个问题,如何把pdf文件添加到word中,而不是只添加图标,下面是解决方案: 1.用word 打开pdf文件: 2.打开word文件: 3.把1中的pdf文件复制粘贴 到2中的word文件 ...
- Git 常用命令速查表(图文+表格)【转】
转自:http://www.jb51.net/article/55442.htm 一. Git 常用命令速查 git branch 查看本地所有分支git status 查看当前状态 git comm ...
- Linux kernel suspend resume学习:2.6.35与3.0.35比较【转】
转自:http://blog.csdn.net/njuitjf/article/details/18317149 Linux kernel suspend resume学习:2.6.35与3.0.35 ...
- 2015多校第7场 HDU 5378 Leader in Tree Land 概率DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378 题意:一棵n个节点的树.对其节点进行标号(1~n).求恰好存在k个节点的标号是其节点所在子树的最 ...
- Makefile系列之二 : 命令
一.显示命令 echo “@”字符可以控制命令是否在屏幕上显示,如 @echo 正在编译XXX模块...... 输出: 正在编译XXX模块...... 如果没有“@"则输出 : echo ...
- tornado write render redirect IP
write 用法( self.flush() ) render (跳转指定网页)用法 redirect(跳转指定路由)用法 self.request.remote_ip 显示用户 IP 地址 less ...
- h5游戏制作
前言: 好久没更新博客了,以前很多都不会,所以常常写博客总结,倒是现在有点点经验了就懒了.在过去的几个月里,在canvas游戏框架方面,撸过了CreateJS,玩得了Egret,又学过PIXI.js. ...
- 递归遍历JSON树
递归遍历JSON树 前几天有个人问我,json串的层级无限深,但在json串中的key是已知的,在json串中的value,有些事Object,有些是Array,如何把这些层级无限深的key所对应的v ...
- 三十八 ThreadLocal
在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. 但是局部变量也有问题,就是在函数调用的 ...