1.柔性数组

2024-05-15 07:12
文章标签 数组 柔性

本文主要是介绍1.柔性数组,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.柔性数组

我们先来介绍一下什么是柔性数组:

在C语言中,柔性数组(Flexible Array)并不是一个标准的术语,但它通常指的是结构体中最后一个元素是一个没有指定大小的数组。这种结构体设计允许在运行时动态分配数组的大小,从而提供了更大的灵活性

这里给一串代码来解释一下:

struct S
{int i;int a[0];//柔性数组成员
};

但是呢有的编译器会报错无法编译这时候我们可以改成这样的:

struct st_type
{int i;int a[];//柔性数组成员
};
1.1柔性数组的特点:

结构中的柔性数组成员前面必须至少一个其他成员。

sizeof返回的这种结构大小不包括柔性数组的内存

包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小。以适应柔性数组的预期大小。

下面我给出一个例子:

typedef struct S
{int i;//柔性数组成员前面必须至少一个其他成员。int a[0];//柔性数组成员
};
int main()
{printf("%d\n", sizeof(type_a));//输出的是4就说明sizeof返回的这种结构大小不包括柔性数组的内存return 0;
}

第三个特点怎么解释:

 柔性数组的这个特点意味着在使用  malloc()  函数为包含柔性数组成员的结构体动态分配内存时,需要分配的内存大小不仅要包括结构体本身的大小,还要额外分配足够的空间来容纳柔性数组的元素。

就是我们在创建一个结构体变量的时候我不是:

struct S s不是这样创建。

柔性数组成员不是这样开辟空间是使用malloc函数进行的。用malloc把包含柔性数组的结构体创建到堆上 :

malloc(sizeof(struct S)+5*sizeof(int))

这里的sizeof(struct S)只包含柔性数组前面的成员大小,然后再加上柔性数组的大小(这个空间你随意创建)


具体来说,当你使用  malloc()  为一个结构体分配内存时,你需要计算出结构体的大小,然后根据柔性数组的预期大小来增加额外的内存分配。这是因为柔性数组的大小在编译时是未知的,它需要在下面是一个具体的例子来解释这个特点:
假设我们有一个结构体  MyStruct  ,它包含一个整型成员  size  和一个柔性数组成员  data  :运行时根据实际情况来确定。

typedef struct {int size; // 结构体的其他成员int data[]; // 柔性数组成员
} MyStruct;

 如果我们想要为这个结构体分配内存,并且柔性数组的预期大小是10个整型元素,那么我们需要这样分配内存:

int main() {int n = 10; // 柔性数组的预期大小// 分配结构体和柔性数组的内存MyStruct *myStruct = malloc(sizeof(MyStruct) + sizeof(int) * n);if (myStruct != NULL) {// 初始化结构体的其他成员myStruct->size = n;// 使用柔性数组...// ...// 释放内存free(myStruct);} else {fprintf(stderr, "Memory allocation failed\n");}return 0;
}

在这个例子中,我们首先计算了结构体的大小(  sizeof(MyStruct)  ),然后根据柔性数组的预期大小(  n  个整型元素)计算了额外需要分配的内存大小(  sizeof(int) * n  )。接着,我们使用  malloc()  函数将这两部分内存大小相加,为结构体和柔性数组分配了足够的内存
这样,我们就可以在运行时动态地为柔性数组分配内存,并且可以按照需要调整柔性数组的大小。这种灵活性是柔性数组设计的核心优势之一。 

1.2柔性数组的使用
#include <stdio.h>
#include <stdlib.h>
typedef struct type_a
{int i;int a[0];
};int main()
{int i = 0;type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));//业务处理p->i = 100;for(i=0; i<100; i++){p->a[i] = i;}free(p);return 0;
}

这样的柔性数组成员a,相当于获得了100个整型元素的连续空间。

1.3柔性数组的优势

上述的type_a结构也可以设计为下面的结构,也能完成同样的效果。

#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{int i;int *p_a;
}type_a;
int main()
{type_a *p = (type_a *)malloc(sizeof(type_a));p->i = 100;p->p_a = (int *)malloc(p->i*sizeof(int));//业务处理for(i=0; i<100; i++){p->p_a[i] = i;}//释放空间free(p->p_a);p->p_a = NULL;free(p);
p = NULL;return 0;
}

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

2.总结c/c++中程序内存区域划分

C/C++程序内存分配的几个区域:
1.栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
《函数栈帧的创建和销毁》
堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由0S回收。分配方式类似于链表。
数据段(静态区):(static)存放全局变量、静态数据。程序结束后由系统释放。
代码段:存放函数体(类成员函数和全局函数)的二进制代码。

  

这篇关于1.柔性数组的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/991153

相关文章

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };

PHP7扩展开发之数组处理

前言 这次,我们将演示如何在PHP扩展中如何对数组进行处理。要实现的PHP代码如下: <?phpfunction array_concat ($arr, $prefix) {foreach($arr as $key => $val) {if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {$arr[

Go 数组赋值问题

package mainimport "fmt"type Student struct {Name stringAge int}func main() {data := make(map[string]*Student)list := []Student{{Name:"a",Age:1},{Name:"b",Age:2},{Name:"c",Age:3},}// 错误 都指向了最后一个v// a

码蹄集部分题目(2024OJ赛9.4-9.8;线段树+树状数组)

1🐋🐋配对最小值(王者;树状数组) 时间限制:1秒 占用内存:64M 🐟题目思路 MT3065 配对最小值_哔哩哔哩_bilibili 🐟代码 #include<bits/stdc++.h> using namespace std;const int N=1e5+7;int a[N],b[N],c[N],n,q;struct QUERY{int l,r,id;}que

【第0006页 · 数组】寻找重复数

【前言】本文以及之后的一些题解都会陆续整理到目录中,若想了解全部题解整理,请看这里: 第0006页 · 寻找重复数         今天想讨论的一道题在 LeetCode 上评论也是颇为“不错”。有一说一,是道好题,不过我们还是得先理解了它才算真正的好题。这里我们展示一种使用二进制的做法,希望能帮到你哟! 【寻找重复数】给定一个包含 n + 1 个整数的数组 nums ,其数字都