《C++ 对象模型》第19页有这样一句话
C程序员的巧计有时候却成为c++程序员的陷阱。例如把单一元素的数组放在一个struct的末尾,于是每个struct objects可以拥有可变数组的数组:

struct mumble
{/* stuff */char pc[1];
};//从文件或标准输入装置中取得一个字符串
//然后为struct 本身和该字符配置足够的内存struct mumble * pmumbl = (struct mumble*)malloc(sizeof(struct mumble) + strlen(string) +1);
strcpy(&mumble.pc,string);

正好之前看MCP++的cache acess组件的时候也发现THashMap等结构体在结构体末尾使用了单一元素的数组,说明这一技巧确实用的广泛,现在看看其原理:
结构体的末尾定义了一个char数组,只分配了1个字符。那怎么能说是可变大小数组。
malloc函数分配了一堆的内存。大小为结构体+字符串+1(字符串结束符)
指针pmumbl指向的是malloc所分配的整个内存,而pmumbl->pc指向的是这块内存的第一个字节,因为malloc操作为整个string分配了足够的内存,所以在strcpy的时候,虽然溢出了pc的内存范围,但没有溢出struct的内存范围,使得strcpy的结果就是合理的且可控的。相当于struct拥有了可变大小的数组

C++中 public、protected、private内的声明顺序可以被保证,但是这三个关键字的布局是不同的。因此总的排列顺序并不能被保证。因此,不一定能实现struct的可变大小的数组,建议是不要那么做。
下面看一下代码验证:

#include <iostream>
#include <string.h>
using namespace std;typedef struct mumble
{/* stuff */char pc[1];
} mumble;
int main(int argc, char **argv){mumble raw;raw.pc[0] = 'a';cout << "raw " << sizeof(raw) << endl;char str[10] = "abcdefgxa";mumble* mumptr = (mumble*)malloc(sizeof(mumble) + strlen(str));strcpy_s(mumptr->pc,strlen(str) + 1, str);cout << "mumptr " << sizeof(*mumptr) << endl;cout << mumptr->pc << endl;free(mumptr);
}

打印结果:sizeof并不能获取mumptr的真实大小,但是通过下标访问确实能够访问到pc

raw 1
mumptr 1
abcdefgxa

内存分布图:

会发现内存中确实有值:

所以以后定义可变包结构时候,结构中没有可变包的大小,而是只要在结构里最后加一个元素的字节数组就可以。

参考:
https://blog.csdn.net/qq_35749455/article/details/116356006

https://blog.csdn.net/weixin_30855761/article/details/99864866?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-3.pc_relevant_default&utm_relevant_index=5

C语言技巧:把单一元素的数组放在末尾,struct可以拥有可变大小的数组相关推荐

  1. 关于理解《C++ 对象模型》中:把单一元素的数组放在末尾,struct可以拥有可变大小的数组...

    这一章在第19页,写的好深奥,我竟然没看明白在说什么--之后再看了几遍,终于明白了. 原文: C程序员的巧计有时候却成为c++程序员的陷阱.例如把单一元素的数组放在一个struct的末尾,于是每个st ...

  2. php创建数组教程,PHP中使用array函数新建一个数组

    PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集合 ...

  3. delphi 获取数组长度_C++可变长的数组,老司机手把手教你实现!

    01 实现自定义的可变长数组类型 假设我们要实现一个会自动扩展的数组,要实现什么函数呢?先从下面的main函数给出的实现,看看有什么函数是需要我们实现的. int main(){ MyArray a; ...

  4. C++ 手把手教你实现可变长的数组

    01 实现自定义的可变长数组类型 假设我们要实现一个会自动扩展的数组,要实现什么函数呢?先从下面的main函数给出的实现,看看有什么函数是需要我们实现的. int main() {MyArray a; ...

  5. LeetCode 540. 有序数组中的单一元素(c语言实现)

    540. 有序数组中的单一元素 给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次. 请你找出并返回只出现一次的那个数. 你设计的解决方案必须满足 O(log n) 时间 ...

  6. 「 每日一练,快乐水题 」540. 有序数组中的单一元素

    ✅力扣原题: 力扣链接:540. 有序数组中的单一元素 ✅题目简述: 给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次. 请你找出并返回只出现一次的那个数. 你设计的解 ...

  7. 540. 有序数组中的单一元素 golang

    540. 有序数组中的单一元素 golang func singleNonDuplicate(nums []int) int {if len(nums) <= 1 {return nums[0] ...

  8. LeetCode 540. 有序数组中的单一元素(Single Element in a Sorted Array) 42

    540. 有序数组中的单一元素 540. Single Element in a Sorted Array 题目描述 每日一算法2019/6/14Day 42LeetCode540. Single E ...

  9. 540. 有序数组中的单一元素

    540. 有序数组中的单一元素 给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数. 示例 1: 输入: [1,1,2,3,3,4,4,8,8] 输出: 2 示例 ...

最新文章

  1. MATLAB 2014a (8.3) Compiler Runtime (MCR)
  2. js倒计时天时分秒php,JS制作分秒倒计时器
  3. 分享一个我现在用的Eclipse(ZendStudio)的PHP黑色背景主题,喜欢的请留言拿走。...
  4. Jenkins入门指南
  5. 目标函数,代价函数,损失函数
  6. 6 追前沿,领略SET化架构衍化与设计
  7. MySQL表的操作(二)
  8. ios cannot use “@throw“ with objective-c exceptions disabled 问题解决方案
  9. UE4之UMG用户界面
  10. 触发器及其应用实验报告总结_2020年中考总复习: 光现象、透镜及其应用知识点总结...
  11. c语言数字游戏程序,C语言实现数字游戏
  12. UE4 实时渲染原理优化策略笔记
  13. 金沙滩开发板单片机学习笔记(2)
  14. TGRS2022/遥感:An Empirical Study of Remote Sensing Pretraining遥感预训练的实证研究
  15. vue日历排班组件_vue之手把手教你写日历组件
  16. 流体机械原理及设计08
  17. ThinkPad T460s BIOS设置实现U盘启动
  18. 维度建模——维度建模与数据仓库概述
  19. KindEditor 自定义插件
  20. golang GF框架

热门文章

  1. postgres 判断null_PostgreSQL NULLIF()用法及代码示例
  2. vue 扫码页面限制区域_Vue.js 单页面多路由区域操作的实例详解
  3. 无忧企业系统的getshell
  4. HTML滚动条S默认最小值,css修改滚动条默认样式
  5. 画毛毛虫代码计算机图形学,考试计算机图形学考试计算机图形学.docx
  6. activiti mysql 版本_Mysql8.0.17版本不能自动创建activiti表的坑
  7. JS实现文本中查找并替换字符
  8. npm dev run 报错
  9. gulp webpack整合
  10. python3基础:字符串、文本文件