【结丹系列】 柔性数组

简介: C进阶之柔性数组

动态内存管理


柔性数组

C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
typedef struct st_type
{
int i;
int a[];//柔性数组成员
}type_a;

柔性数组的特点

1.结构中的柔性数组成员前面必须至少一个其他成员。
2.sizeof 返回的这种结构大小不包括柔性数组的内存。
3.包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct S
{
    int n;
    int arr[];//柔性数组成员
}S;
int main() {
    struct S* ps = (struct S*)malloc(sizeof(struct S) + 40);
    if (ps == NULL) {
        return 1;
    }
    ps->n = 100;
    int i = 0;
    for (i = 0; i < 10; i++) {
        ps->arr[i] = i;
    }
    for (i = 0; i < 10; i++) {
        printf("%d", ps->arr[i]);
    }
    struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 80);
    if (ptr != NULL)
    {
        ps = ptr;
        ptr = NULL;
    }
    free(ps);
    ps = NULL;
    return 0;
}
//这样柔性数组成员arr,相当于获得了10个整型元素的连续空间。

image-20220723103944818

柔性数组的优点

第一个好处是:方便内存释放

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给
用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你
不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好
了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
第二个好处是:这样有利于访问速度.
连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正
你跑不了要用做偏移量的加法来寻址)

动态内存函数的介绍

2.1 mallocfree

C语言提供了一个动态内存开辟的函数:

void* malloc (size_t size);

这个函数向内存申请一块 连续可用的空间,并返回指向这块空间的指针。

如果开辟成功,则返回一个指向开辟好空间的指针。

如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。

返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己

来决定。

如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器.

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:

void free (void* ptr);

free函数用来释放动态开辟的内存。

如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。

如果参数 ptr 是NULL指针,则函数什么事都不做。

malloc和free都声明在 stdlib.h 头文件中。

相关文章
MindOpt APL 达摩院自己的建模语言!
MindOpt建模语言(MindOpt Algebraic Programming Language, MindOpt APL, 简称为MAPL)是MindOpt团队研发的一种代数建模语言。相比与其他的语言,MAPL语法相对较少且自然,很贴近数学语言。用MAPL描述数学规划模型与用数学公式进行描述非常类似。
MindOpt APL 达摩院自己的建模语言!
|
8月前
|
存储 人工智能 自然语言处理
0 代码焦虑!阿里云 Bolt.diy 一键解锁你的专属网站,30 分钟惊艳上线
Bolt.diy 是阿里云推出的智能化建站工具,基于函数计算 FC 和百炼模型服务,通过自然语言描述即可快速生成网站。无需本地配置环境,3分钟完成部署,适合各水平用户。支持个性化定制、域名绑定及数据备份,安全可靠。无论是个人博客还是企业官网,都能轻松实现。立即领取免费额度体验:[部署链接](https://www.aliyun.com/solution/tech-solution/fc-bolt-diy?utm_content=g_1000403257)。
298 4
|
前端开发
vuecli3打包报警告:chunk chunk-common [mini-css-extract-plugin] Conflicting order.
vuecli3打包报警告:chunk chunk-common [mini-css-extract-plugin] Conflicting order.
494 0
vuecli3打包报警告:chunk chunk-common [mini-css-extract-plugin] Conflicting order.
十进制与二进制、八进制、十六进制之间的互相转换,本文让你全部理清
十进制与二进制、八进制、十六进制之间的互相转换,本文让你全部理清
2214 0
十进制与二进制、八进制、十六进制之间的互相转换,本文让你全部理清
|
8月前
|
JSON JavaScript 前端开发
gRPC技术中的gRPC到HTTP的转换
从上述内容,我们可以看到,gRPC到HTTP的转换并没有改变gRPC强大的性能和可扩展性。它只是让这些强大的功能能更好地适应不同的环境和需求,兼容了更广泛的网络设施。所以,技术总是在变化,并且始终在寻找更好的平衡点,以满足不断变化的业务需求。我们也应该持续学习,掌握这些新的变化,以便更好地解决实际问题。
288 11
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
623 22
|
存储 算法 数据安全/隐私保护
基于A律压缩的PCM脉冲编码调制通信系统simulink建模与仿真
本项目展示了一种基于MATLAB 2022a的脉冲编码调制(PCM)算法,用于将模拟信号转换为数字信号。A律压缩是非均匀量化方法之一,适用于语音信号编码,能够提高信噪比和编码效率。核心代码已提供,并附有详细中文注释和操作视频。A律压缩通过调整量化间隔来适应人耳的听觉特性,减少量化噪声,实现高质量的语音通信。此技术广泛应用于电话通信、VoIP和数字音频处理等领域。
|
存储 网络协议 C语言
【C语言】位操作符详解 - 《开心消消乐》
位操作符用于在位级别上进行操作。C语言提供了一组位操作符,允许你直接操作整数类型的二进制表示。这些操作符可以有效地处理标志、掩码、位字段等低级编程任务。
561 8
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
835 2
|
Python
Sublime Text Python 代码提示插件 Anaconda
Sublime Text Python 代码提示插件 Anaconda
362 1