IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言弹性数组成员 -> 正文阅读

[C++知识库]C语言弹性数组成员

假设需要定义一个结构,这个结构包括一个len字段和一个data字段。分别表示这个数据的长度和对应的数据。我们一般有以下几个方法这样做。

引言

方法一:定长数组

第一种方法就是使用定长数组。即对数组设置一个足够大的缓冲区。如:

struct vstring1 {
    int len;
    char data[N];
};

其中N是一个表示字符串最大长度的宏。考虑到字节对齐,则这个结构体的大小 大于等于:

sizeof(int) + sizeof(char) * N;

这样做既限制了我们使用字符串的长度(最大为N), 也会浪费许多的内存(可能大多数字符串并不需要N个字符串)。

方法二: 使用指针

定义如下的数据结构:

struct vstring2 {
    int len;
    char *data;
};

这种在很多代码中也非常常见,这种需要内存申请两次。第一次是为结构体vstring2申请内存,第二次是为结构体成员data申请内存。相比于使用定长数组。使用指针浪费的内存就只有一个指针域的大小了。缺点就是有可能我们只释放了结构体指针,忘记释放里面的成员data的内存,导致内存泄漏。其次的话,这两次内存申请是不连续的,可能对性能有一定的影响。

方法三:struct hack

第三种做法是声明data数组的长度是1,然后动态地分配每一个字符串:

struct vstring3 {
    int len;
    char data[1];
};
...
struct vstring3 *str = malloc(sizeof(struct vstring3) + n -1);
str->len = n;

这里使用了一种"欺骗"的方法,分配比该结构声明时应具有的内存(这个例子中是n-1个字符)更多的内存,然后使用这些内存存储data数组额外的元素。这种方法称为"struct hack"。
因为struct hack技术非常有用,所以从C99开始提供了弹性数组成员 (flexible array member)来达到同样的目的。

弹性数组成员

弹性数组成员是指结构的最后一个成员是数组时,其长度可以省略:

struct vstring {
    int len;
    char data[];
};

data数组的长度在为vstring结构分配内存时确定:

struct vstring *str = malloc(sizeof(struct vstring) + n);
str->len = n;

对于弹性数组成员,需要注意两点:

  1. 在计算结构体大小时(sizeof(struct vstring)),数组成员并不占用结构体的大小。
#include <stdio.h>
struct vstring {
    int len;
    char data[];
};

int main() 
{
    printf("%u, %u\n", sizeof(int), sizeof(struct vstring)); // 4,4 
    return 0;
}
  1. 数组一定是结构体的最后一个成员。否则会编译报错。

参考文献

  1. https://blog.csdn.net/gatieme/article/details/64131322
  2. <<C语言程序设计现代方法>> 第2版修订版
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-02 10:37:50  更:2021-08-02 10:38:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 1:38:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码