柔性数组和C语言内存划分

news2024/12/23 20:40:11

柔性数组和C语言内存划分

    • 1. 柔性数组
      • 1.1 柔性数组的特点:
      • 1.2 柔性数组的使用
      • 1.3 柔性数组的优势
    • 2. 总结C/C++中程序内存区域划分

1. 柔性数组

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。

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

例如:

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

有些编译器会报错⽆法编译可以改成:

typedef struct st_type
{
	int i;
	int a[];//柔性数组成员
}type_a;

1.1 柔性数组的特点:

  • 结构中的柔性数组成员前面必须至少⼀个其他成员。
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构⽤malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
#include <stdio.h>
struct St
{
	int n;
	int arr[0];
};

int main()
{
	printf("%zd\n", sizeof(struct St));
	return 0;
}

运行结果如图:
在这里插入图片描述

1.2 柔性数组的使用

#include <stdio.h>
#include <stdlib.h>
struct St
{
	char c;
	int n;
	int arr[0];
};

int main()
{
	struct St* ps = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	ps->c = 'w';
	ps->n = 100;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//数组空间不够
	struct St* ptr = (struct St*)realloc(ps, sizeof(struct St) + 15 * sizeof(int));
	if (ptr != NULL)
	{
		ps = ptr;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	//...继续使用
	for (i = 10; i < 15; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 15; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
	printf("%d\n", ps->n);
	printf("%c\n", ps->c);
	//释放
	free(ps);
	ps = NULL;
	return 0;
}

运行结果如图:
在这里插入图片描述

1.3 柔性数组的优势

我们也可以模拟实现柔性数组的效果,代码如下:

#include <stdio.h>
#include <stdlib.h>
typedef struct St
{
	char c;
	int n;
	int* arr;
}st;
int main()
{
	st* ps = (st*)malloc(sizeof(st));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	ps->c = 'w';
	ps->n = 100;
	ps->arr = (int*)malloc(10 * sizeof(int));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;
	}
	//扩容
	int* tmp = (int*)realloc(ps->arr, 15 * sizeof(int));
	if (tmp != NULL)
	{
		ps->arr = tmp;
		tmp = NULL;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	//使用
	for (i = 10; i < 15; i++)
	{
		ps->arr[i] = i;
	}
	for (i = 0; i < 15; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
	printf("%d\n", ps->n);
	printf("%c", ps->c);
	//释放
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}

运行结果如图:
在这里插入图片描述

上述 代码1代码2 可以完成同样的功能,但是 方法1 的实现有两个好处:

第一个好处是:方便内存释放
如果我们的代码是在⼀个给别⼈⽤的函数中,你在里面做了⼆次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给用户⼀个结构体指针,用户做⼀次free就可以把所有的内存也给释放掉。

第二个好处是:这样有利于访问速度.
连续的内存有益于提⾼访问速度,也有益于减少内存碎片。

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

在这里插入图片描述
C/C++程序内存分配的几个区域:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1403156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决Git添加.gitignore文件后不生效的问题

1. 问题描述 如上图所示&#xff0c;在已存在.gitignore文件且已经提交过的Git管理的项目中&#xff0c;其中.class、.jar文件以及.idea目录内的内容全部都还是被Git管理了&#xff0c;可见.gitignore文件并没有生效。 2. 原因发现 .gitignore文件只能作用于 Untracked Files…

vue+elementUI el-select 中 没有加clearable出现一个或者多个×清除图标问题

1、现象&#xff1a;下方截图多清除图标了 2、在全局common.scss文件中加一个下方的全局样式noClear 3、在多清除图标的组件上层div加noClear样式 4、清除图标去除成功

iOS应用程序混淆加固原理及逆向工具介绍

概要 本文将介绍iOS应用程序混淆加固的原理和常见的加固类型&#xff0c;以及介绍一些常用的逆向工具。同时还会介绍一种代码虚拟化技术&#xff0c;用于进一步保护应用程序不被逆向分析。 引言 移动应用程序开发面临着越来越严峻的安全挑战&#xff0c;特别是在越狱设备上…

k8s1.27.2版本二进制高可用集群部署

文章目录 环境软件版本服务器系统初始化设置关于etcd签名证书etcd集群部署负载均衡器组件安装设置关于k8s自签证书自签CAkube-apiserver 自签证书kube-controller-manager自签证书kube-scheduler自签证书kube-proxy 自签证书admin 自签证书 控制平面节点组件部署**部署kube-api…

Uni-App三甲医院、医保定点三甲医院在线预约挂号系统源码

医院在线预约挂号系统是一种方便患者预约挂号的系统&#xff0c;患者可以通过该系统进行预约挂号&#xff0c;省去了到医院现场排队等待的时间&#xff0c;提高了就诊效率。随着医院信息化水平的不断发展&#xff0c;医院在线预约挂号管理系统已成为医院管理中不可或缺的一部分…

如何在Linux部署JumpServer堡垒机并实现远程访问本地服务

文章目录 前言1. 安装Jump server2. 本地访问jump server3. 安装 cpolar内网穿透软件4. 配置Jump server公网访问地址5. 公网远程访问Jump server6. 固定Jump server公网地址 前言 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpS…

KAGGLE · GETTING STARTED CODE COMPETITION 图像风格迁移 示例代码阅读

本博文阅读的代码来自于I’m Something of a Painter Myself | Kaggle倾情推荐&#xff1a; Monet CycleGAN Tutorial | Kaggle 数据集说明 I’m Something of a Painter Myself | Kaggle Files monet_jpg - 300 Monet paintings sized 256x256 in JPEG formatmonet_tfrec -…

Redis相关面试题大全

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于java面试题系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基…

如何快速制作动态gif图?制作gif动图就这么简单

静图和动图是图像的两种不同形式。静图是一张静止不动的图片&#xff0c;没有任何动作或变化。而动图则是由一系列静止的图像组成&#xff0c;通过快速连续播放这些图像&#xff0c;可以形成看起来像是有动作的效果。简单来说&#xff0c;静图是静止的&#xff0c;而动图是具有…

Copilot安装和使用最全教程

背景 Copilot 是一款由 GitHub 和 OpenAI 合作开发的代码辅助工具。它基于 OpenAI 的大型语言模型 GPT-3.5&#xff0c;专为帮助软件开发者提升编程效率而设计 Copilot的主要功能是通过理解用户输入的代码注释或部分代码片段、自动生成或补全代码&#xff0c;本文主要介绍copi…

常规二分查找中遇到的问题

以前我们写二分查找的时候&#xff0c;是这么写的&#xff1a; public static int binarySearch2(int []a,int target){int i0,ja.length-1;while(i<j){int mid(ij)/2;if(a[mid]target){return mid;}else if(a[mid]<target){imid1;}else {jmid-1;}}return -1;} 这么写&…

Conda python管理环境environments 一 从入门到精通

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装Conda python运行的包和环境管理 入门 使用 conda&#xff0c;可以创建、导出、列出、删除和更新 具有不同 Python 版本和/或 安装在其中的软件包。在两者之间切换或移动 环境称为激活环境。您…

如何在CentOS8使用宝塔面板本地部署Typecho个人网站并实现公网访问【内网穿透】

文章目录 前言1. 安装环境2. 下载Typecho3. 创建站点4. 访问Typecho5. 安装cpolar6. 远程访问Typecho7. 固定远程访问地址8. 配置typecho 前言 Typecho是由type和echo两个词合成的&#xff0c;来自于开发团队的头脑风暴。Typecho基于PHP5开发&#xff0c;支持多种数据库&#…

Java 面向对象案例01(黑马)

文字版格斗游戏 在Javabean类中定义方法的形参的数据类型可以是什么&#xff1f; 在JavaBean类中&#xff0c;方法的形参的数据类型可以是任何合法的Java数据类型&#xff0c;包括基本数据类型&#xff08;如int、char、boolean等&#xff09;、引用数据类型&#xff08;如Str…

【文件处理】spring boot 文件处理

接收文件 PostMappingpublic result<String> add(MultipartFile file) throws IOException {// 得到目标文件夹File directory new File("file");//如果文件夹不存在就创建if(!directory.exists()){directory.mkdirs();}//文件名称String fileName file.getO…

分子生成工具应用案例+流程 - Pocket Crafter

2023年10月9日&#xff0c;诺华公司的Lingling Shen和He Wang在Chemrxiv上发表了文章《Pocket Crafter: A 3D Generative Modeling Based Workflow for the Rapid Generation of Hit Molecules in Drug Discovery》&#xff0c;介绍了他们分子生成在hit finding项目应用中的pip…

python+appium自动化测试-Appium并发测试之python启动appium服务

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

【加速计算】从硬件、软件到网络互联,AI时代下的加速计算技术

AI、元宇宙、大模型…每一个火爆名词的背后都代表着巨大的算力需求。据了解,AI模型所需的算力每100天就要翻一倍,远超摩尔定律的18-24个月。5年后,AI所需的算力规模将是今天的100万倍以上。 在这种背景下,加速计算提供了必要的计算能力和内存,其解决方案涉及硬件、软件和…

ChatGPT:关于 OpenAI 的 GPT-4工具,你需要知道的一切

ChatGPT&#xff1a;关于 OpenAI 的 GPT-4工具&#xff0c;你需要知道的一切 什么是GPT-3、GPT-4 和 ChatGPT&#xff1f;ChatGPT 可以做什么&#xff1f;ChatGPT-4 可以做什么&#xff1f;ChatGPT 的费用是多少&#xff1f;GPT-4 与 GPT-3.5 有何不同&#xff1f;ChatGPT 如何…

红黑树(超详解)

文章目录 前言红黑树的概念红黑树的实现红黑树的结构 insert 前言 上一篇文章我们讲了AVL树,但是AVL树只是一个过渡,我们实际当中用的更多另外一颗树还是红黑树. 也不能说红黑树就是AVL树的改进,它是用另外一种方式来控制. 这棵树更抽象一些,下一步我们来看一下. 红黑树的概…