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中一开始就用到了. ============================================== ...
随机推荐
- 多线程伪共享FalseSharing
1. 伪共享产生: 在SMP架构的系统中,每个CPU核心都有自己的cache,当多个线程在不同的核心上,并且某线程修改了在同一个cache line中的数据时,由于cache一致性原则,其他核心cac ...
- 移动端测试===Android内存泄露和GC机制(转)
本文转自:https://www.testwo.com/article/1153 1.前言 Hello,小伙伴们,相信大家在项目测试中都遇到过内存泄露问题,小编也着实爬过很多坑.比如小编所测项目,更换 ...
- 【bzoj1649】Cow Roller Coaster
傻逼dp题. dp[i][j]表示用了i长度已花费成本j所能得到的价值. 然后枚举一下铁轨随便做了. 不行就sort一下. #include<bits/stdc++.h> #define ...
- 2015多校第6场 HDU 5360 Hiking 贪心,优先队列
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5360 题意:给定n个人,现在要邀请这些人去远足,但每个人同意邀请的条件是当前已经同意去远足的人数c必须 ...
- 关于:TypeConverter 无法从 System.String 转换
TypeConverter 无法从 System.String 转换 处理方法: 1: [DX Support Team: The issue was resolved by its Owner] i ...
- Can't load standard profile: GRAY.pf
报错: java.lang.IllegalArgumentException: Can't load standard profile: GRAY.pf at java.awt.color.ICC_P ...
- 【python】发送邮件
从网上找了一些用python发邮件的教程,学习一下: 1.发送普通的文本邮件 http://www.cnblogs.com/xiaowuyi/archive/2012/03/17/2404015.ht ...
- 魔法上网之Ubuntu部署“酸酸”
“酸酸”,即s*h*a*d*o*w*s*o*c*k*s,用于魔法上网,用python写成. 在ubuntu环境下,用pip包管理工具可以非常方便地安装“酸酸”服务:ssserver. 先安装pip(假 ...
- 关于rem的一点总结【原创】
关于rem的一点总结 最近在写一个关于小说阅读的webApp,由于没有借用任何框架,所以很多底层的内容都需要自己去解决,幸好的是这次只是关于移动端的内容,还不至于去向着jquery的方向码代码.言归正 ...
- AC日记——[ZJOI2012]网络 bzoj 2816
2816 思路: 多个LCT: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 10005 #define l ...