服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 深入了解一下C语言中的柔性数组

深入了解一下C语言中的柔性数组

2023-03-02 15:33Jambo! C/C++

柔性数组是在C99中定义的,即结构体的最后一个元素允许是未知大小的数组,这就叫柔性数组。这篇文章将通过简单的示例为大家介绍一下柔性数组的使用,感兴趣的可以了解一下

什么是柔性数组

柔性数组是在C99中定义的

结构体的最后一个元素允许是未知大小的数组,这就叫柔性数组

柔性数组的长度可以写成0,也可以不规定数组长度

下面两种写法都是正确的

?
1
2
3
4
5
struct S
{
int i;
int a[0];//柔性数组成员
}
?
1
2
3
4
5
struct S
{
int i;
int a[];//柔性数组成员
}
  • 结构体中的柔性数组成员前面至少有一个其他成员
  • sizeof返回的这种结构体的大小不包括柔性数组的大小
  • 包含柔性数组成员的结构体用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大
    小,以适应柔性数组的预期大小。

柔性数组的使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef struct S
{
    int i;
    char c[];//c是柔性数组
}S;
 
int main()
{
    S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char));
    if (p == NULL)
    {
        perror("malloc");
        return 1;
    }
    p->i = 10;
    for (int i = 0; i < 10; i++)
    {
        p->c[i] = 'a';
    }
    free(p);
    p = NULL;
    return 0;
}

在malloc开辟空间时,开辟空间大小为sizeof(S) + 10 * sizeof(char),前面的sizeof(S)其实是表示结构体中int i的大小,后面则是给c开辟了10个字节大小的连续空间

如果觉得前面开辟空间小了,数组c不够长,还可以用realloc函数对内存大小进行调整

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main()
{
    S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char));
    if (p == NULL)
    {
        perror("malloc");
        return 1;
    }
    p->i = 10;
    
    S* ptr = (S*)realloc(p, sizeof(S) + 20 * sizeof(char));
    if (ptr == NULL)
    {
        perror("realloc");
        return 1;
    }
    p = ptr;
    for (int i = 0; i < 20; i++)
    {
        p->c[i] = 'a';
    }
 
    free(p);
    p = NULL;
    return 0;
}

其实我们也可以写出另一种形式的结构体,它的功能与柔性数组类似

?
1
2
3
4
5
typedef struct S2
{
    it i;
    char* c;
}S2;

对于这个结构体的使用如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main()
{
    S2* p = (S2*)malloc(sizeof(S2));
    p->i = 10;
    p->c = (char*)malloc(10 * sizeof(char));
    for (int i = 0; i < 10; i++)
    {
        p->c[i] = 'a';
    }
 
    free(p->c);
    p->c = NULL;
    free(p);
    p = NULL;
 
    return 0;
}

为了使用这个结构体,需要先给结构体开辟一个空间S2* p = (S2*)malloc(sizeof(S2));然后再需要动态开辟一个块空间让c指向

这种写法需要开辟2次内存,同样在最后释放内存是,也需要free2次

所以就可以看出柔性数组的好处:

第 一个是方便内存释放

因为不论是我们在使用时或给别人写一个函数让别人使用时,如果在里面做了二次内存分配,可能别人使用时并不会知道结构体内部还有一个成员需要释放。所以就需要把内存一次性分配好,在最后释放一次内存就可以了

第二个是加快访问

如果二次内存分配,就会在内存中产生一些内存碎片,这样即浪费了空间也不利于访问

到此这篇关于深入了解一下C语言中的柔性数组的文章就介绍到这了,更多相关C语言柔性数组内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_64116522/article/details/128982081

延伸 · 阅读

精彩推荐
  • C/C++C语言实现各种排序算法实例代码(选择,冒泡,插入,归并,希尔,快排,堆排序,计数)

    C语言实现各种排序算法实例代码(选择,冒泡,插入,归并,希尔,快排

    排序算法是算法之中相对基础的,也是各门语言的必学的算法,这篇文章主要介绍了C语言实现各种排序算法(选择,冒泡,插入,归并,希尔,快排,堆排序,计数)的相...

    微小冷3622022-01-21
  • C/C++C++中结构体的类型定义和初始化以及变量引用

    C++中结构体的类型定义和初始化以及变量引用

    这篇文章主要介绍了C++中结构体的类型定义和初始化以及变量引用,是C++入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网11112021-03-13
  • C/C++C++实现简易的五子棋小游戏

    C++实现简易的五子棋小游戏

    这篇文章主要为大家详细介绍了C++实现简易的五子棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    Prepare_y9732022-11-22
  • C/C++c语言实现的几种常用排序算法

    c语言实现的几种常用排序算法

    C,语言常用的排序方法有很多种。比如说冒泡排序,直接交换排序,直接选择排序,直接插入排序,二分插入排序,快速排序,归并排序等等,下面这篇文章主要给大...

    蜗牛的书10012021-11-12
  • C/C++opencv检测直线方法之形态学方法

    opencv检测直线方法之形态学方法

    这篇文章主要为大家详细介绍了opencv检测直线方法之形态学方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    恬梦12712021-07-16
  • C/C++C语言实现像素鸟游戏

    C语言实现像素鸟游戏

    这篇文章主要为大家详细介绍了C语言实现像素鸟游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    无限的菜鸟3592022-12-01
  • C/C++详解C++元编程之Parser Combinator

    详解C++元编程之Parser Combinator

    借助C++的constexpr能力,可以轻而易举的构造Parser Combinator,对用户定义的字符串(User defined literal)释放了巨大的潜力。...

    华为云开发者社区3432021-11-08
  • C/C++C语言由浅入深讲解文件的操作上篇

    C语言由浅入深讲解文件的操作上篇

    C语言具有操作文件的能力,比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。与其他编程语言相比,C语言文件操作的接口相当...

    _奇奇4112022-11-03