结构体中数组放在最后位置的问题

2023-11-20

以下出自“C Programming FAQS”.

先看下面的代码:

struct name {
	int namelen;
	char namestr[1];
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name) - 1 + strlen(newname) + 1);
		//-1 for initial [1]; +1 for \0
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		strcpy(ret->namestr, newname);
	}
	return ret;
}
这个函数分配了一个name结构的实例并调整它的大小,以便将请求的名称置入namestr域中。

也可以把变长的元素声明为很大,而不是很小。

#define MAX 100
struct name {
	int namelen;
	char namestr[MAX];
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name) - MAX + strlen(newname) + 1);
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		strcpy(ret->namestr, newname);
	}
	return ret;
}
当然,真正安全的正确做法是使用字符指针,而不是数组。

struct name {
	int namelen;
	char *namep;
};

struct name *makename(char *newname) {
	struct name *ret = malloc(sizeof(struct name));
	if(ret != NULL) {
		ret->namelen = strlen(newname);
		ret->namep = malloc(ret->namelen + 1);
		if(ret->namep == NULL) {
			free(ret);
			ret = NULL;
		}
		strcpy(ret->namep, newname);
	}
	return ret;
}
以上代码需要申请和释放没存空间两次。考虑到存储的数据类型是字符,为了保持连续性,可以直截了当的将两次malloc调用合成一次,这样也就可以只用一次调用free就能释放了。

struct name *makename(char *newname) {
	char *buf = malloc(sizeof(struct name) + strlen(newname) + 1);
	struct name *ret = (struct name *)buf;
	ret->namelen = strlen(newname);
	ret->namep = buf + sizeof(struct name);
	strcpy(ret->namep, newname);
	return ret;
}
但是,像这样用一次malloc调用将第二个区域接上的技巧只有在第二个区域是char型数组的时候才能移植。对于任何大一些的类型,对齐就变得很重要,必须保持。

C99引入了“灵活数组域”概念,允许结构的最后一个域省略数组的大小。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构体中数组放在最后位置的问题 的相关文章

随机推荐

  • el-select实现懒加载

    先看一个线上的演示示例 https code juejin cn pen 7273352811440504889 背景 我们在实际开发中经常遇到这样的需求 el select实现懒加载 用通俗的话说 为了增加响应速度 就是初始下拉只展示50
  • 网络流量在线分析系统的设计与实现

    编译环境 visual studio2019 安装并配置winpcap和pthreads库函数 1 配置环境 1 1 安装vscode 参考微信公众号 软件安装管家 1 2 安装MinGW w64 下载地址 添加链接描述 安装参考博客 Mi
  • 实验二 程序流程控制

    1 编写程序计算 1 3 5 7 99 之和 summ 0 for i in range 1 100 summ summ i print 和为 summ 2 编写程序 计算 2 4 6 8 100 之和 summ 0 for i in ra
  • 计算机网络试题

    一 选择题 1 OSI模型与TCP IP模型都具有的层次是 A 会话层 网络层和物理层 B 表示层 会话层和数据链路层 C 网络层 传输层和应用层 D 表示层 数据链路层和物理层 2 对于计算机网络体系结构 下列关于第N层和第N 1层的关系
  • 蓝桥杯:字符串

    题目链接 include
  • notepad++字符串替换

    删除空白行 在编辑选项里面包括很多功能 编辑 gt 行操作 gt 移除空行 包括空白字符 行首添加字符串 按CTRL F 选择替换页签 选择正则表达式 查找目标 设置为 替换为 设置自己想要替换的字符串 特殊字符需要添加 进行转义 行尾添加
  • 【MySQL】34道SQL综合练习详解(员工表、部门表、工资等级表)

    文章目录 一 34道SQL综合练习 二 测试使用的数据表 三 创建测试表的SQL语句 一 34道SQL综合练习 1 查询取得每个部门最高工资的人员信息 select e ename t from emp e join select dept
  • 如何使用PCL将XYZRGB点云转换为彩色mesh模型

    如何使用PCL将XYZRGB点云转换为彩色mesh模型 最近完成了一个使用RGBD传感器 构建物体模型的小demo 其中有点难的最后一步是如何将获得的物体点云变成彩色mesh模型 效果图如下 从点云变成彩色mesh 其实整体的步骤可以总结如
  • M1 macbook上安装docker 编译内核 并使用qemu启动内核。

    一 编译内核并通过qemu启动内核 1 在M1上安装docker这个就不用提供步骤了 网上自行搜索 2 在M1上pull一个ubuntu的容器 docker pull ubuntu 18 04 docker images REPOSITOR
  • 卡尔曼滤波及其MATLAB程序

    今天写了个卡尔曼滤波的小程序 希望对有需要的同学有点帮助 卡尔曼滤波是一个很常用的滤波算法 与维纳滤波相比有很多长处 这里我们把Kalman Filter简称为KF KF的基本思想是 采用信号 噪声 状态空间模型 利用前一时刻的状态最优估计
  • 学习python笔记01

    一 python是什么 人生苦短 我用python python是一门解释型语言 边解释边运行 与编译型语言的区别是 编译型语言是先编译后运行 python语言的特点 1 优雅 2 明确 3 简单 python是一个完全面向对象语言 具有强
  • 纯java实现相片转素描

    1 实例演示图片转素描效果 首先我们来看一下具体的效果 在项目中添加依赖
  • unity制作一个可以自由滑动收缩的历史记录功能。

    公司在做一款模拟经营类的卖车游戏 需要一个简单的历史记录功能 放在左上角 记录最近20条的收入 支出记录 超过2秒不动则收起 收起时展示最近的一个消息记录 用到的组件是ScrollView 使用方法可以参考我写过的一篇博客 ScrollVi
  • Input.GetAxis _ Unity3d

    Input GetAxis 获取轴 static function GetAxis axisName string float Description描述 Returns the value of the virtual axis iden
  • 【论文精读】时序逻辑应用之模型预测控制Model Predictive Control with Signal Temporal Logic Specifications

    前言 因为天天写代码实在是太枯燥了 所以读点其他东西来调剂一下 这样科研进度不至于停下 前面读了几篇关于时序逻辑学习的文章 今天来了解一下时序逻辑公式在控制中的应用 Raman V Donze A Maasoumy M Murray R M
  • Android Studio编译失败问题(aapt2)

    Android Studio 3 1编译时出错 org gradle api tasks TaskExecutionException Execution failed for task app mergeDebugResources at
  • 心灵鸡汤

    心灵鸡汤 比尔盖茨不想弯腰去捡100美金 浪费了1秒 时间是最宝贵 有限的时间资源最大化 如果你不够优秀 人脉是不值钱的 它不是追求来的 而是吸引来的 只有等价的交换 才能得到合理的帮助 虽然听起来很冷 但这是事实 与凤凰同飞 必是俊鸟 与
  • AESCBCUtil

    import javax crypto Cipher import javax crypto spec IvParameterSpec import javax crypto spec SecretKeySpec import org ap
  • 面试必问的 CAS ,要多了解

    前言 CAS Compare and Swap 即比较并替换 实现并发算法时常用到的一种技术 Doug lea大神在java同步器中大量使用了CAS技术 鬼斧神工的实现了多线程执行的安全性 CAS的思想很简单 三个参数 一个当前内存值V 旧
  • 结构体中数组放在最后位置的问题

    以下出自 C Programming FAQS 先看下面的代码 struct name int namelen char namestr 1 struct name makename char newname struct name ret