【C语言进阶】柔性数组

简介: 【C语言进阶】柔性数组

d90ba57d473b4adda401841b4af504a2.gif

0ce1e3cda68e4dde91ac99d3c17a4192.gif

 在C99中,结构中最后一个元素允许是未知大小的数组,这就叫做柔性数组成员

以下是柔性数组的两种写法:

//写法一:
struct S
{
  int n;
  char c;
  char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};
//写法二:
struct S
{
  int n;
  char c;
  char arr[0];//0也说明它的大小是未知的 - - 柔性数组成员
};

一:柔性数组的特点

  • 结构体中的柔性数组成员前面必须至少一个其他成员
  • sizeof返回的这种结构体大小不包括柔性数组的大小
  • 包含柔性数组成员的结构体用malloc函数进行动态内存分配,并且分配的内存应该大于结构体的大小,以适应柔性数组的预期大小。
//利用malloc进行空间分配
struct S
{
  int n;
  char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};
int main()
{
  printf("%d\n", sizeof(struct S));
  struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//后面的10 * sizeof(char)就是为arr数组开辟的
  return 0;
}

二:柔性数组的使用

#include <stdio.h>
#include <stdlib.h>
struct S
{
  int n;
  char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};
int main()
{
  printf("%d\n", sizeof(struct S));
  struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//后面的10 * sizeof(char)就是为arr数组开辟的
  if (ps == NULL)
  {
    perror("malloc");
    return 1;
  }
  //使用
  ps->n = 100;
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    ps->arr[i] = 'a';
  }
  for (i = 0; i < 10; i++)
  {
    printf("%c ", ps->arr[i]);
  }
  //增容
  struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 20 * sizeof(char));
  if (ptr == NULL)
  {
    perror("realloc");
    return 1;
  }
  else
  {
    ps = ptr;
  }
  //释放
  free(ps);
  ps = NULL;
  return 0;
}

三:模拟实现柔性数组

struct S
{
  int n;
  char* arr;
};
int main()
{
  struct S* ps = (struct S*)malloc(sizeof(struct S));
  if (ps == NULL)
  {
    perror("malloc");
    return 1;
  }
  //为arr开辟指向的空间
  ps->arr = (char*)malloc(sizeof(char) * 10);//开辟10个字符型的空间
  if (ps->arr == NULL)
  {
    perror("malloc");
    return 1;
  }
  //使用
  ps->n = 100;
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    ps->arr[i] = 'a';
  }
  for (i = 0; i < 10; i++)
  {
    printf("%c ", ps->arr[i]);
  }
  //增容
  char* ptr = (char*)realloc(ps->arr, sizeof(char) * 20);
  if (ptr == NULL)
  {
    perror("realloc");
    return 1;
  }
  else
  {
    ps->arr = ptr;
  }
  //使用
  for (i = 0; i < 20; i++)
  {
    *((ps->arr)+i) = 'b';
  }
  for (i = 0; i < 20; i++)
  {
    printf("%c ", *((ps->arr) + i));
  }
  //释放
  free(ps->arr);
  ps->arr = NULL;
  free(ps);
  ps = NULL;
  return 0;
}

常规的柔性数组,只需要malloc一次,free一次,并且空间是连续的,而模拟实现的柔性数组需要malloc两次,free两次,并且空间可能不连续。malloc的次数越多,越容易出错,可能出现忘记释放导致内存泄漏问题。此外,malloc的次数越多,产生的内存碎片就越多,内存利用率就会下降,造成内存空间浪费,malloc次数越少,产生的北村碎片就越少,内存利用率就会增加,会避免内存空间浪费。并且空间连续的情况下,访问数据的时候效率就会更高。

 今天的分享到这里就结束啦!如果觉得文章还不错的话,记得三连支持一下小恐龙,您的支持就是小恐龙前进的动力!


目录
相关文章
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
5月前
|
数据库 C语言
C语言进阶 文件操作知识(上)
C语言进阶 文件操作知识(上)
36 3
|
5月前
|
存储 C语言
C语言进阶 文件操作知识(下)
C语言进阶 文件操作知识(下)
37 2
|
5月前
|
存储 编译器 数据库
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
【再识C进阶5(上)】详细介绍C语言文件操作——文件是用于存储数据
|
5月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
43 0
|
6月前
|
编译器 C语言 C++
从C语言到C++_21(模板进阶+array)+相关笔试题(下)
从C语言到C++_21(模板进阶+array)+相关笔试题
47 2
|
5月前
|
存储 C语言 C++
【C语言刷题系列】水仙花数的打印及进阶
【C语言刷题系列】水仙花数的打印及进阶
|
6月前
|
C语言
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(二)
我们可以通过创建并定义符号常量NUMBER,来作为判断是否胜利的标准。如三子棋中,令NUMBER为3,则这八个方向中有任意一个方向达成3子连珠,则连珠的这个棋子所代表的玩家获胜。
61 1
|
6月前
|
算法 C语言 C++
万字详解:C语言三子棋进阶 + N子棋递归动态判断输赢(一)
三子棋游戏设计的核心是对二维数组的把握和运用。
66 1
|
6月前
|
C语言
C语言(14)----柔性数组
C语言(14)----柔性数组
36 1